/* mceliece6688128f.c - Classic McEliece for libgcrypt
 * Copyright (C) 2023-2024 Simon Josefsson <simon@josefsson.org>
 *
 * This file is part of Libgcrypt.
 *
 * Libgcrypt is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * Libgcrypt is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, see <https://www.gnu.org/licenses/>.
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 */

/* This file is extracted from libmceliece. */

/*
 * libmceliece is hereby placed into the public domain.
 *
 * [SPDX-License-Identifier](https://spdx.dev/ids/):
 * [LicenseRef-PD-hp](https://cr.yp.to/spdx.html)
 * OR
 * [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html)
 * OR
 * [0BSD](https://spdx.org/licenses/0BSD.html)
 * OR
 * [MIT-0](https://spdx.org/licenses/MIT-0.html)
 * OR
 * [MIT](https://spdx.org/licenses/MIT.html)
 *
 * libmceliece is based on the official Classic McEliece software, which
 * was written by Tung Chou. See the following papers for the major
 * algorithms used for speed inside that software:
 *
 * * Daniel J. Bernstein, Tung Chou, Peter Schwabe. "McBits: fast
 *   constant-time code-based cryptography." CHES 2013.
 *   [https://tungchou.github.io/papers/mcbits.pdf](https://tungchou.github.io/papers/mcbits.pdf)
 *
 * * Tung Chou. "McBits revisited." CHES 2017.
 *   [https://tungchou.github.io/papers/mcbits_revisited.pdf](https://tungchou.github.io/papers/mcbits_revisited.pdf)
 *
 * The official Classic McEliece software includes `ref`, `vec`, `sse`, and
 * `avx` implementations; libmceliece includes only `vec` and `avx`.
 *
 * The following components of libmceliece are from Daniel J. Bernstein:
 *
 * * Small [changes](download.html#changelog)
 *   for namespacing, portability, etc.
 *
 * * Software to compute control bits (also used in the official software).
 *   See the following paper: Daniel J. Bernstein. "Verified fast formulas
 *   for control bits for permutation networks." 2020.
 *   [https://cr.yp.to/papers.html#controlbits](https://cr.yp.to/papers.html#controlbits)
 *
 * * `crypto_sort/int32`. See [https://sorting.cr.yp.to](https://sorting.cr.yp.to).
 *
 * * Infrastructure to build a library with automatic run-time selection of
 *   implementations based on the run-time CPU and a database of
 *   benchmarks. This infrastructure was introduced in
 *   [`lib25519`](https://lib25519.cr.yp.to), with some extensions and
 *   adaptations in libmceliece.
 *
 * * Various software for tests and benchmarks. This is based on
 *   public-domain code in the SUPERCOP benchmarking framework.
 *
 * This file is generated by mceliece6688128f.sh from these files:
 *
 * libmceliece-20230612/include-build/crypto_declassify.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/params.h
 * libmceliece-20230612/inttypes/crypto_intN.h
 * libmceliece-20230612/inttypes/crypto_intN.h
 * libmceliece-20230612/inttypes/crypto_intN.h
 * libmceliece-20230612/inttypes/crypto_uintN.h
 * libmceliece-20230612/inttypes/crypto_uintN.h
 * libmceliece-20230612/inttypes/crypto_uintN.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/vec.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/benes.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/bm.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/fft.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/gf.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/hash.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/operations.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/util.h
 * libmceliece-20230612/crypto_kem/6688128f/vec/benes.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/bm.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/fft.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/gf.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/vec.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c
 * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "g10lib.h"
#include "mceliece6688128f.h"

#define int8 crypto_int8
#define uint8 crypto_uint8
#define int16 crypto_int16
#define uint16 crypto_uint16
#define int32 crypto_int32
#define uint32 crypto_uint32
#define int64 crypto_int64
#define uint64 crypto_uint64

static void
randombytes (uint8_t *out, size_t outlen)
{
  _gcry_randomize (out, outlen, GCRY_STRONG_RANDOM);
}

/* from libmceliece-20230612/include-build/crypto_declassify.h */
#ifndef crypto_declassify_h
#define crypto_declassify_h

static void crypto_declassify(void *crypto_declassify_v,long long crypto_declassify_vlen) {
  (void) crypto_declassify_v;
  (void) crypto_declassify_vlen;
}

#endif

/* from libmceliece-20230612/crypto_kem/6688128f/vec/params.h */
#ifndef PARAMS_H
#define PARAMS_H

#define GFBITS 13
#define SYS_N 6688
#define SYS_T 128

#define COND_BYTES ((1 << (GFBITS-4))*(2*GFBITS - 1))
#define IRR_BYTES (SYS_T * 2)

#define PK_NROWS (SYS_T*GFBITS)
#define PK_NCOLS (SYS_N - PK_NROWS)
#define PK_ROW_BYTES ((PK_NCOLS + 7)/8)

#define SYND_BYTES ((PK_NROWS + 7)/8)

#define GFMASK ((1 << GFBITS) - 1)

#endif


/* from libmceliece-20230612/inttypes/crypto_intN.h */
#ifndef crypto_int64_h
#define crypto_int64_h

#define crypto_int64 int64_t

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_negative_mask(crypto_int64 crypto_int64_x)
{
  return crypto_int64_x >> (64-1);
}

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_nonzero_mask(crypto_int64 crypto_int64_x)
{
  return crypto_int64_negative_mask(crypto_int64_x) | crypto_int64_negative_mask(-crypto_int64_x);
}

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_zero_mask(crypto_int64 crypto_int64_x)
{
  return ~crypto_int64_nonzero_mask(crypto_int64_x);
}

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_positive_mask(crypto_int64 crypto_int64_x)
{
  crypto_int64 crypto_int64_z = -crypto_int64_x;
  crypto_int64_z ^= crypto_int64_x & crypto_int64_z;
  return crypto_int64_negative_mask(crypto_int64_z);
}

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_unequal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
{
  crypto_int64 crypto_int64_xy = crypto_int64_x ^ crypto_int64_y;
  return crypto_int64_nonzero_mask(crypto_int64_xy);
}

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_equal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
{
  return ~crypto_int64_unequal_mask(crypto_int64_x,crypto_int64_y);
}

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_smaller_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
{
  crypto_int64 crypto_int64_xy = crypto_int64_x ^ crypto_int64_y;
  crypto_int64 crypto_int64_z = crypto_int64_x - crypto_int64_y;
  crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_x);
  return crypto_int64_negative_mask(crypto_int64_z);
}

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_min(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
{
  crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x;
  crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x;
  crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y);
  crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z);
  crypto_int64_z &= crypto_int64_xy;
  return crypto_int64_x ^ crypto_int64_z;
}

GCC_ATTR_UNUSED
static crypto_int64 crypto_int64_max(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y)
{
  crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x;
  crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x;
  crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y);
  crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z);
  crypto_int64_z &= crypto_int64_xy;
  return crypto_int64_y ^ crypto_int64_z;
}

GCC_ATTR_UNUSED
static void crypto_int64_minmax(crypto_int64 *crypto_int64_a,crypto_int64 *crypto_int64_b)
{
  crypto_int64 crypto_int64_x = *crypto_int64_a;
  crypto_int64 crypto_int64_y = *crypto_int64_b;
  crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x;
  crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x;
  crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y);
  crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z);
  crypto_int64_z &= crypto_int64_xy;
  *crypto_int64_a = crypto_int64_x ^ crypto_int64_z;
  *crypto_int64_b = crypto_int64_y ^ crypto_int64_z;
}

#endif

/* from libmceliece-20230612/inttypes/crypto_intN.h */
#ifndef crypto_int16_h
#define crypto_int16_h

#define crypto_int16 int16_t

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_negative_mask(crypto_int16 crypto_int16_x)
{
  return crypto_int16_x >> (16-1);
}

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_nonzero_mask(crypto_int16 crypto_int16_x)
{
  return crypto_int16_negative_mask(crypto_int16_x) | crypto_int16_negative_mask(-crypto_int16_x);
}

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_zero_mask(crypto_int16 crypto_int16_x)
{
  return ~crypto_int16_nonzero_mask(crypto_int16_x);
}

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_positive_mask(crypto_int16 crypto_int16_x)
{
  crypto_int16 crypto_int16_z = -crypto_int16_x;
  crypto_int16_z ^= crypto_int16_x & crypto_int16_z;
  return crypto_int16_negative_mask(crypto_int16_z);
}

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_unequal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
{
  crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y;
  return crypto_int16_nonzero_mask(crypto_int16_xy);
}

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_equal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
{
  return ~crypto_int16_unequal_mask(crypto_int16_x,crypto_int16_y);
}

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_smaller_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
{
  crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y;
  crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y;
  crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_x);
  return crypto_int16_negative_mask(crypto_int16_z);
}

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_min(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
{
  crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x;
  crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x;
  crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y);
  crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z);
  crypto_int16_z &= crypto_int16_xy;
  return crypto_int16_x ^ crypto_int16_z;
}

GCC_ATTR_UNUSED
static crypto_int16 crypto_int16_max(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y)
{
  crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x;
  crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x;
  crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y);
  crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z);
  crypto_int16_z &= crypto_int16_xy;
  return crypto_int16_y ^ crypto_int16_z;
}

GCC_ATTR_UNUSED
static void crypto_int16_minmax(crypto_int16 *crypto_int16_a,crypto_int16 *crypto_int16_b)
{
  crypto_int16 crypto_int16_x = *crypto_int16_a;
  crypto_int16 crypto_int16_y = *crypto_int16_b;
  crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x;
  crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x;
  crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y);
  crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z);
  crypto_int16_z &= crypto_int16_xy;
  *crypto_int16_a = crypto_int16_x ^ crypto_int16_z;
  *crypto_int16_b = crypto_int16_y ^ crypto_int16_z;
}

#endif

/* from libmceliece-20230612/inttypes/crypto_intN.h */
#ifndef crypto_int32_h
#define crypto_int32_h

#define crypto_int32 int32_t

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_negative_mask(crypto_int32 crypto_int32_x)
{
  return crypto_int32_x >> (32-1);
}

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_nonzero_mask(crypto_int32 crypto_int32_x)
{
  return crypto_int32_negative_mask(crypto_int32_x) | crypto_int32_negative_mask(-crypto_int32_x);
}

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_zero_mask(crypto_int32 crypto_int32_x)
{
  return ~crypto_int32_nonzero_mask(crypto_int32_x);
}

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_positive_mask(crypto_int32 crypto_int32_x)
{
  crypto_int32 crypto_int32_z = -crypto_int32_x;
  crypto_int32_z ^= crypto_int32_x & crypto_int32_z;
  return crypto_int32_negative_mask(crypto_int32_z);
}

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_unequal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
{
  crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y;
  return crypto_int32_nonzero_mask(crypto_int32_xy);
}

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_equal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
{
  return ~crypto_int32_unequal_mask(crypto_int32_x,crypto_int32_y);
}

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_smaller_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
{
  crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y;
  crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y;
  crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_x);
  return crypto_int32_negative_mask(crypto_int32_z);
}

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_min(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
{
  crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x;
  crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x;
  crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y);
  crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z);
  crypto_int32_z &= crypto_int32_xy;
  return crypto_int32_x ^ crypto_int32_z;
}

GCC_ATTR_UNUSED
static crypto_int32 crypto_int32_max(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y)
{
  crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x;
  crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x;
  crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y);
  crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z);
  crypto_int32_z &= crypto_int32_xy;
  return crypto_int32_y ^ crypto_int32_z;
}

GCC_ATTR_UNUSED
static void crypto_int32_minmax(crypto_int32 *crypto_int32_a,crypto_int32 *crypto_int32_b)
{
  crypto_int32 crypto_int32_x = *crypto_int32_a;
  crypto_int32 crypto_int32_y = *crypto_int32_b;
  crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x;
  crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x;
  crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y);
  crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z);
  crypto_int32_z &= crypto_int32_xy;
  *crypto_int32_a = crypto_int32_x ^ crypto_int32_z;
  *crypto_int32_b = crypto_int32_y ^ crypto_int32_z;
}

#endif

/* from libmceliece-20230612/inttypes/crypto_uintN.h */
#ifndef crypto_uint64_h
#define crypto_uint64_h

#define crypto_uint64 uint64_t
#define crypto_uint64_signed int64_t

GCC_ATTR_UNUSED
static crypto_uint64_signed crypto_uint64_signed_negative_mask(crypto_uint64_signed crypto_uint64_signed_x)
{
  return crypto_uint64_signed_x >> (64-1);
}

GCC_ATTR_UNUSED
static crypto_uint64 crypto_uint64_nonzero_mask(crypto_uint64 crypto_uint64_x)
{
  return crypto_uint64_signed_negative_mask(crypto_uint64_x) | crypto_uint64_signed_negative_mask(-crypto_uint64_x);
}

GCC_ATTR_UNUSED
static crypto_uint64 crypto_uint64_zero_mask(crypto_uint64 crypto_uint64_x)
{
  return ~crypto_uint64_nonzero_mask(crypto_uint64_x);
}

GCC_ATTR_UNUSED
static crypto_uint64 crypto_uint64_unequal_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
{
  crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y;
  return crypto_uint64_nonzero_mask(crypto_uint64_xy);
}

GCC_ATTR_UNUSED
static crypto_uint64 crypto_uint64_equal_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
{
  return ~crypto_uint64_unequal_mask(crypto_uint64_x,crypto_uint64_y);
}

GCC_ATTR_UNUSED
static crypto_uint64 crypto_uint64_smaller_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
{
  crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y;
  crypto_uint64 crypto_uint64_z = crypto_uint64_x - crypto_uint64_y;
  crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_x ^ (((crypto_uint64) 1) << (64-1)));
  return crypto_uint64_signed_negative_mask(crypto_uint64_z);
}

GCC_ATTR_UNUSED
static crypto_uint64 crypto_uint64_min(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
{
  crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x;
  crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x;
  crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1)));
  crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z);
  crypto_uint64_z &= crypto_uint64_xy;
  return crypto_uint64_x ^ crypto_uint64_z;
}

GCC_ATTR_UNUSED
static crypto_uint64 crypto_uint64_max(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y)
{
  crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x;
  crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x;
  crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1)));
  crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z);
  crypto_uint64_z &= crypto_uint64_xy;
  return crypto_uint64_y ^ crypto_uint64_z;
}

GCC_ATTR_UNUSED
static void crypto_uint64_minmax(crypto_uint64 *crypto_uint64_a,crypto_uint64 *crypto_uint64_b)
{
  crypto_uint64 crypto_uint64_x = *crypto_uint64_a;
  crypto_uint64 crypto_uint64_y = *crypto_uint64_b;
  crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x;
  crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x;
  crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1)));
  crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z);
  crypto_uint64_z &= crypto_uint64_xy;
  *crypto_uint64_a = crypto_uint64_x ^ crypto_uint64_z;
  *crypto_uint64_b = crypto_uint64_y ^ crypto_uint64_z;
}

#endif

/* from libmceliece-20230612/inttypes/crypto_uintN.h */
#ifndef crypto_uint16_h
#define crypto_uint16_h

#define crypto_uint16 uint16_t
#define crypto_uint16_signed int16_t

GCC_ATTR_UNUSED
static crypto_uint16_signed crypto_uint16_signed_negative_mask(crypto_uint16_signed crypto_uint16_signed_x)
{
  return crypto_uint16_signed_x >> (16-1);
}

GCC_ATTR_UNUSED
static crypto_uint16 crypto_uint16_nonzero_mask(crypto_uint16 crypto_uint16_x)
{
  return crypto_uint16_signed_negative_mask(crypto_uint16_x) | crypto_uint16_signed_negative_mask(-crypto_uint16_x);
}

GCC_ATTR_UNUSED
static crypto_uint16 crypto_uint16_zero_mask(crypto_uint16 crypto_uint16_x)
{
  return ~crypto_uint16_nonzero_mask(crypto_uint16_x);
}

GCC_ATTR_UNUSED
static crypto_uint16 crypto_uint16_unequal_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
{
  crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y;
  return crypto_uint16_nonzero_mask(crypto_uint16_xy);
}

GCC_ATTR_UNUSED
static crypto_uint16 crypto_uint16_equal_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
{
  return ~crypto_uint16_unequal_mask(crypto_uint16_x,crypto_uint16_y);
}

GCC_ATTR_UNUSED
static crypto_uint16 crypto_uint16_smaller_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
{
  crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y;
  crypto_uint16 crypto_uint16_z = crypto_uint16_x - crypto_uint16_y;
  crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_x ^ (((crypto_uint16) 1) << (16-1)));
  return crypto_uint16_signed_negative_mask(crypto_uint16_z);
}

GCC_ATTR_UNUSED
static crypto_uint16 crypto_uint16_min(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
{
  crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x;
  crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x;
  crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1)));
  crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z);
  crypto_uint16_z &= crypto_uint16_xy;
  return crypto_uint16_x ^ crypto_uint16_z;
}

GCC_ATTR_UNUSED
static crypto_uint16 crypto_uint16_max(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y)
{
  crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x;
  crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x;
  crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1)));
  crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z);
  crypto_uint16_z &= crypto_uint16_xy;
  return crypto_uint16_y ^ crypto_uint16_z;
}

GCC_ATTR_UNUSED
static void crypto_uint16_minmax(crypto_uint16 *crypto_uint16_a,crypto_uint16 *crypto_uint16_b)
{
  crypto_uint16 crypto_uint16_x = *crypto_uint16_a;
  crypto_uint16 crypto_uint16_y = *crypto_uint16_b;
  crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x;
  crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x;
  crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1)));
  crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z);
  crypto_uint16_z &= crypto_uint16_xy;
  *crypto_uint16_a = crypto_uint16_x ^ crypto_uint16_z;
  *crypto_uint16_b = crypto_uint16_y ^ crypto_uint16_z;
}

#endif

/* from libmceliece-20230612/inttypes/crypto_uintN.h */
#ifndef crypto_uint32_h
#define crypto_uint32_h

#define crypto_uint32 uint32_t
#define crypto_uint32_signed int32_t

GCC_ATTR_UNUSED
static crypto_uint32_signed crypto_uint32_signed_negative_mask(crypto_uint32_signed crypto_uint32_signed_x)
{
  return crypto_uint32_signed_x >> (32-1);
}

GCC_ATTR_UNUSED
static crypto_uint32 crypto_uint32_nonzero_mask(crypto_uint32 crypto_uint32_x)
{
  return crypto_uint32_signed_negative_mask(crypto_uint32_x) | crypto_uint32_signed_negative_mask(-crypto_uint32_x);
}

GCC_ATTR_UNUSED
static crypto_uint32 crypto_uint32_zero_mask(crypto_uint32 crypto_uint32_x)
{
  return ~crypto_uint32_nonzero_mask(crypto_uint32_x);
}

GCC_ATTR_UNUSED
static crypto_uint32 crypto_uint32_unequal_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
{
  crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y;
  return crypto_uint32_nonzero_mask(crypto_uint32_xy);
}

GCC_ATTR_UNUSED
static crypto_uint32 crypto_uint32_equal_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
{
  return ~crypto_uint32_unequal_mask(crypto_uint32_x,crypto_uint32_y);
}

GCC_ATTR_UNUSED
static crypto_uint32 crypto_uint32_smaller_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
{
  crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y;
  crypto_uint32 crypto_uint32_z = crypto_uint32_x - crypto_uint32_y;
  crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_x ^ (((crypto_uint32) 1) << (32-1)));
  return crypto_uint32_signed_negative_mask(crypto_uint32_z);
}

GCC_ATTR_UNUSED
static crypto_uint32 crypto_uint32_min(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
{
  crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x;
  crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x;
  crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1)));
  crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z);
  crypto_uint32_z &= crypto_uint32_xy;
  return crypto_uint32_x ^ crypto_uint32_z;
}

GCC_ATTR_UNUSED
static crypto_uint32 crypto_uint32_max(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y)
{
  crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x;
  crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x;
  crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1)));
  crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z);
  crypto_uint32_z &= crypto_uint32_xy;
  return crypto_uint32_y ^ crypto_uint32_z;
}

GCC_ATTR_UNUSED
static void crypto_uint32_minmax(crypto_uint32 *crypto_uint32_a,crypto_uint32 *crypto_uint32_b)
{
  crypto_uint32 crypto_uint32_x = *crypto_uint32_a;
  crypto_uint32 crypto_uint32_y = *crypto_uint32_b;
  crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x;
  crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x;
  crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1)));
  crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z);
  crypto_uint32_z &= crypto_uint32_xy;
  *crypto_uint32_a = crypto_uint32_x ^ crypto_uint32_z;
  *crypto_uint32_b = crypto_uint32_y ^ crypto_uint32_z;
}

#endif

/* from libmceliece-20230612/crypto_kem/6688128f/vec/vec.h */
#ifndef VEC_H
#define VEC_H



typedef uint64_t vec;

static inline vec vec_setbits(vec b)
{
	vec ret = -b;

	return ret;
}

static inline vec vec_set1_16b(uint16_t v)
{
	vec ret;

	ret = v;
	ret |= ret << 16;
	ret |= ret << 32;

	return ret;
}

static inline void vec_copy(vec * out, vec * in)
{
	int i;

	for (i = 0; i < GFBITS; i++)
		out[i] = in[i];
}

static inline vec vec_or_reduce(vec * a)
{
	int i;
	vec ret;

	ret = a[0];
	for (i = 1; i < GFBITS; i++)
		ret |= a[i];

	return ret;
}

static inline int vec_testz(vec a)
{
	a |= a >> 32;
	a |= a >> 16;
	a |= a >> 8;
	a |= a >> 4;
	a |= a >> 2;
	a |= a >> 1;

	return (a&1)^1;
}

static void vec_mul(vec *, const vec *, const vec *);
static void vec_sq(vec *, vec *);
static void vec_inv(vec *, vec *);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.h */
/*
  This file is for Benes network related functions
*/

#ifndef BENES_H
#define BENES_H


static void benes(vec *, const unsigned char *, int);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/bm.h */
/*
  This file is for the inversion-free Berlekamp-Massey algorithm
  see https://ieeexplore.ieee.org/document/87857
*/

#ifndef BM_H
#define BM_H


static void bm(vec [][GFBITS], vec [][ GFBITS ]);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h */
/* This file is for implementing the Nassimi-Sahni algorithm */
/* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */
/* See also https://cr.yp.to/papers/controlbits-20200923.pdf */

#ifndef CONTROLBITS_H
#define CONTROLBITS_H




#endif

/* from libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h */
/*
  This file is for Nieddereiter decryption
*/

#ifndef DECRYPT_H
#define DECRYPT_H

static int decrypt(unsigned char *, const unsigned char *, const unsigned char *);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h */
/*
  This file is for Niederreiter encryption
*/
/* 20230102 djb: rename encrypt() as pke_encrypt() */

#ifndef ENCRYPT_H
#define ENCRYPT_H

static void pke_encrypt(unsigned char *, const unsigned char *, unsigned char *);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h */
#ifndef fft_consts_h
#define fft_consts_h




#endif

/* from libmceliece-20230612/crypto_kem/6688128f/vec/fft.h */
/*
  This file is for the Gao-Mateer FFT
  sse http://www.math.clemson.edu/~sgao/papers/GM10.pdf
*/

#ifndef FFT_H
#define FFT_H


static void fft(vec [][GFBITS], vec [][GFBITS]);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h */
#ifndef fft_powers_h
#define fft_powers_h




#endif

/* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h */
#ifndef fft_scalars_2x_h
#define fft_scalars_2x_h




#endif

/* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h */
#ifndef fft_scalars_4x_h
#define fft_scalars_4x_h




#endif

/* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h */
/*
  This file is for transpose of the Gao-Mateer FFT
*/

#ifndef FFT_TR_H
#define FFT_TR_H


static void fft_tr(vec out[][GFBITS], vec in[][ GFBITS ]);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/gf.h */
/*
  This file is for functions for field arithmetic
*/
/* 20221231 djb: const for GF_mul */

#ifndef GF_H
#define GF_H



typedef uint16_t gf;

gf gf_iszero(gf);
gf gf_mul(gf, gf);
gf gf_frac(gf, gf);
gf gf_inv(gf);

static void GF_mul(gf *, const gf *, const gf *);

/* 2 field multiplications */
static inline uint64_t gf_mul2(gf a, gf b0, gf b1)
{
	int i;

	uint64_t tmp=0;
	uint64_t t0;
	uint64_t t1;
	uint64_t t;
	uint64_t mask = 0x0000000100000001;

	t0 = a;
	t1 = b1;
	t1 = (t1 << 32) | b0;

	for (i = 0; i < GFBITS; i++)
	{
		tmp ^= t0 * (t1 & mask);
		mask += mask;
	}

	/**/

	t = tmp & 0x01FF000001FF0000;
	tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);

	t = tmp & 0x0000E0000000E000;
	tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);

	return tmp & 0x00001FFF00001FFF;
}

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/hash.h */

#define shake crypto_xof_shake256

#define crypto_hash_32b(out,in,inlen) \
  shake(out,32,in,inlen)

/* from libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h */
#ifndef int32_sort_h
#define int32_sort_h



#define int32_MINMAX(a,b) \
do { \
  int64_t ab = (int64_t)b ^ (int64_t)a; \
  int64_t c = (int64_t)b - (int64_t)a; \
  c ^= ab & (c ^ b); \
  c >>= 31; \
  c &= ab; \
  a ^= c; \
  b ^= c; \
} while(0)

static void int32_sort(int32_t *x,long long n)
{
  long long top,p,q,r,i;

  if (n < 2) return;
  top = 1;
  while (top < n - top) top += top;

  for (p = top;p > 0;p >>= 1) {
    for (i = 0;i < n - p;++i)
      if (!(i & p))
        int32_MINMAX(x[i],x[i+p]);
    i = 0;
    for (q = top;q > p;q >>= 1) {
      for (;i < n - q;++i) {
        if (!(i & p)) {
          int32_t a = x[i + p];
          for (r = q;r > p;r >>= 1)
            int32_MINMAX(a,x[i+r]);
          x[i + p] = a;
        }
      }
    }
  }
}

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/operations.h */
#ifndef OPERATIONS_H
#define OPERATIONS_H


static void operation_enc(
       unsigned char *c,
       unsigned char *key,
       const unsigned char *pk
);

static void operation_dec(
       unsigned char *key,
       const unsigned char *c,
       const unsigned char *sk
);

static void operation_keypair
(
       unsigned char *pk,
       unsigned char *sk
);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h */
/*
  This file is for public-key generation
*/

#ifndef PK_GEN_H
#define PK_GEN_H


static int pk_gen(unsigned char *, const unsigned char *, uint32_t *, int16_t *, uint64_t *);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h */
/*
  This file is for secret-key generation
*/

#ifndef SK_GEN_H
#define SK_GEN_H



static int genpoly_gen(gf *, gf *);

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h */
/*
  This file is for matrix transposition
*/

#ifndef TRANSPOSE_H
#define TRANSPOSE_H

/* input: in, a 64x64 matrix over GF(2) */
/* output: out, transpose of in */
static inline void transpose_64x64(uint64_t * out, uint64_t * in)
{
	int i, j, s, d;

	uint64_t x, y;
	uint64_t masks[6][2] = {
	                        {0x5555555555555555, 0xAAAAAAAAAAAAAAAA},
	                        {0x3333333333333333, 0xCCCCCCCCCCCCCCCC},
	                        {0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0},
	                        {0x00FF00FF00FF00FF, 0xFF00FF00FF00FF00},
	                        {0x0000FFFF0000FFFF, 0xFFFF0000FFFF0000},
	                        {0x00000000FFFFFFFF, 0xFFFFFFFF00000000}
	                       };

	for (i = 0; i < 64; i++)
		out[i] = in[i];

	for (d = 5; d >= 0; d--)
	{
		s = 1 << d;

		for (i = 0; i < 64; i += s*2)
		for (j = i; j < i+s; j++)
		{
			x = (out[j] & masks[d][0]) | ((out[j+s] & masks[d][0]) << s);
			y = ((out[j] & masks[d][1]) >> s) | (out[j+s] & masks[d][1]);

			out[j+0] = x;
			out[j+s] = y;
		}
	}
}

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h */
#ifndef uint16_sort_h
#define uint16_sort_h



#define uint16_MINMAX(a,b) \
do { \
  uint16_t c = b - a; \
  c >>= 15; \
  c = -c; \
  c &= a ^ b; \
  a ^= c; \
  b ^= c; \
} while(0)

static void uint16_sort(uint16_t *x,long long n)
{
  long long top,p,q,r,i;

  if (n < 2) return;
  top = 1;
  while (top < n - top) top += top;

  for (p = top;p > 0;p >>= 1) {
    for (i = 0;i < n - p;++i)
      if (!(i & p))
        uint16_MINMAX(x[i],x[i+p]);
    i = 0;
    for (q = top;q > p;q >>= 1) {
      for (;i < n - q;++i) {
        if (!(i & p)) {
          int16_t a = x[i + p];
          for (r = q;r > p;r >>= 1)
            uint16_MINMAX(a,x[i+r]);
          x[i + p] = a;
        }
      }
    }
  }
}

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h */
#ifndef uint64_sort_h
#define uint64_sort_h



#define uint64_MINMAX(a,b) \
do { \
  uint64_t c = b - a; \
  c >>= 63; \
  c = -c; \
  c &= a ^ b; \
  a ^= c; \
  b ^= c; \
} while(0)

static void uint64_sort(uint64_t *x,long long n)
{
  long long top,p,q,r,i;

  if (n < 2) return;
  top = 1;
  while (top < n - top) top += top;

  for (p = top;p > 0;p >>= 1) {
    for (i = 0;i < n - p;++i)
      if (!(i & p))
        uint64_MINMAX(x[i],x[i+p]);
    i = 0;
    for (q = top;q > p;q >>= 1) {
      for (;i < n - q;++i) {
        if (!(i & p)) {
          uint64_t a = x[i + p];
          for (r = q;r > p;r >>= 1)
            uint64_MINMAX(a,x[i+r]);
          x[i + p] = a;
        }
      }
    }
  }
}

#endif


/* from libmceliece-20230612/crypto_kem/6688128f/vec/util.h */
/*
  This file is for loading/storing data in a little-endian fashion
*/

#ifndef UTIL_H
#define UTIL_H



static inline void store_i(unsigned char *out, uint64_t in, int i)
{
	int j;

	for (j = 0; j < i; j++)
		out[j] = (in >> (j * 8)) & 0xFF;
}

static inline void store_gf(unsigned char *dest, uint16_t a)
{
	dest[0] = a & 0xFF;
	dest[1] = a >> 8;
}

static inline uint16_t load_gf(const unsigned char *src)
{
	uint16_t a;

	a = src[1];
	a <<= 8;
	a |= src[0];

	return a & GFMASK;
}

static inline uint32_t load4(const unsigned char *src)
{
	uint32_t a;

	a  = src[3]; a <<= 8;
	a |= src[2]; a <<= 8;
	a |= src[1]; a <<= 8;
	a |= src[0];

	return a;
}

static inline void irr_load(vec out[][GFBITS], const unsigned char * in)
{
	int i, j;
	uint64_t v0 = 0, v1 = 0;
	uint16_t irr[ SYS_T ];

	for (i = 0; i < SYS_T; i++)
		irr[i] = load_gf(in + i*2);

	for (i = 0; i < GFBITS; i++)
	{
		for (j = 63; j >= 0; j--)
		{
			v0 <<= 1;
			v1 <<= 1;
			v0 |= (irr[j] >> i) & 1;
			v1 |= (irr[j+64] >> i) & 1;
		}

		out[0][i] = v0;
		out[1][i] = v1;
	}
}

static inline void store8(unsigned char *out, uint64_t in)
{
	out[0] = (in >> 0x00) & 0xFF;
	out[1] = (in >> 0x08) & 0xFF;
	out[2] = (in >> 0x10) & 0xFF;
	out[3] = (in >> 0x18) & 0xFF;
	out[4] = (in >> 0x20) & 0xFF;
	out[5] = (in >> 0x28) & 0xFF;
	out[6] = (in >> 0x30) & 0xFF;
	out[7] = (in >> 0x38) & 0xFF;
}

static inline uint64_t load8(const unsigned char * in)
{
	int i;
	uint64_t ret = in[7];

	for (i = 6; i >= 0; i--)
	{
		ret <<= 8;
		ret |= in[i];
	}

	return ret;
}

#endif


static void crypto_xof_shake256(unsigned char *h,long long hlen,
				const unsigned char *m,long long mlen)
{
  gcry_md_hd_t mdh;
  gcry_err_code_t ec;

  ec = _gcry_md_open (&mdh, GCRY_MD_SHAKE256, 0);
  if (ec)
    log_fatal ("internal md_open failed: %d\n", ec);
  _gcry_md_write (mdh, m, mlen);
  _gcry_md_extract (mdh, GCRY_MD_SHAKE256, h, hlen);
  _gcry_md_close (mdh);
}

/* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.c */
/*
  This file is for Benes network related functions

  For the implementation strategy, see
  https://eprint.iacr.org/2017/793.pdf
*/
/* 20221230 djb: add linker lines */

/* linker define benes */


/* middle layers of the benes network */
static void layer_in(uint64_t data[2][64], uint64_t * bits, int lgs)
{
	int i, j, s;

	uint64_t d;

	s = 1 << lgs;

	for (i = 0; i < 64; i += s*2)
	for (j = i; j < i+s; j++)
	{

		d = (data[0][j+0] ^ data[0][j+s]);
		d &= (*bits++);
		data[0][j+0] ^= d;
		data[0][j+s] ^= d;

		d = (data[1][j+0] ^ data[1][j+s]);
		d &= (*bits++);
		data[1][j+0] ^= d;
		data[1][j+s] ^= d;
	}
}

/* first and last layers of the benes network */
static void layer_ex(uint64_t * data, uint64_t * bits, int lgs)
{
	int i, j, s;

	uint64_t d;

	s = 1 << lgs;

	for (i = 0; i < 128; i += s*2)
	for (j = i; j < i+s; j++)
	{

		d = (data[j+0] ^ data[j+s]);
		d &= (*bits++);
		data[j+0] ^= d;
		data[j+s] ^= d;
	}
}

/* input: r, sequence of bits to be permuted */
/*        bits, condition bits of the Benes network */
/*        rev, 0 for normal application; !0 for inverse */
/* output: r, permuted bits */
static void benes(vec * r, const unsigned char * bits, int rev)
{
	int i, iter, inc;

	const unsigned char *bits_ptr;

	uint64_t r_int_v[2][64];
	uint64_t r_int_h[2][64];
	uint64_t b_int_v[64];
	uint64_t b_int_h[64];

	/**/

	if (rev) { bits_ptr = bits + 12288; inc = -1024; }
	else     { bits_ptr = bits;         inc = 0;    }

	for (i = 0; i < 64; i++)
	{
		r_int_v[0][i] = r[i*2 + 0];
		r_int_v[1][i] = r[i*2 + 1];
	}

	transpose_64x64(r_int_h[0], r_int_v[0]);
	transpose_64x64(r_int_h[1], r_int_v[1]);

	for (iter = 0; iter <= 6; iter++)
	{
		for (i = 0; i < 64; i++)
		{
			b_int_v[i] = load8(bits_ptr); bits_ptr += 8;
		}

		bits_ptr += inc;

		transpose_64x64(b_int_h, b_int_v);

		layer_ex(r_int_h[0], b_int_h, iter);
	}

	transpose_64x64(r_int_v[0], r_int_h[0]);
	transpose_64x64(r_int_v[1], r_int_h[1]);

	for (iter = 0; iter <= 5; iter++)
	{
		for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; }
		bits_ptr += inc;

		layer_in(r_int_v, b_int_v, iter);
	}

	for (iter = 4; iter >= 0; iter--)
	{
		for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; }
		bits_ptr += inc;

		layer_in(r_int_v, b_int_v, iter);
	}

	transpose_64x64(r_int_h[0], r_int_v[0]);
	transpose_64x64(r_int_h[1], r_int_v[1]);

	for (iter = 6; iter >= 0; iter--)
	{
		for (i = 0; i < 64; i++)
		{
			b_int_v[i] = load8(bits_ptr); bits_ptr += 8;
		}

		bits_ptr += inc;

		transpose_64x64(b_int_h, b_int_v);

		layer_ex(r_int_h[0], b_int_h, iter);
	}

	transpose_64x64(r_int_v[0], r_int_h[0]);
	transpose_64x64(r_int_v[1], r_int_h[1]);

	for (i = 0; i < 64; i++)
	{
		r[i*2+0] = r_int_v[0][i];
		r[i*2+1] = r_int_v[1][i];
	}
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/bm.c */
/*
  This file is for implementating the inversion-free Berlekamp-Massey algorithm
  see https://ieeexplore.ieee.org/document/87857

  For the implementation strategy, see
  https://eprint.iacr.org/2017/793.pdf
*/
/* 20221230 djb: add linker lines */

/* linker define bm */
/* linker use vec_mul */
/* linker use gf_inv */



static inline uint16_t mask_nonzero(gf a)
{
	uint32_t ret = a;

	ret -= 1;
	ret >>= 31;
	ret -= 1;

	return ret;
}

static inline uint16_t mask_leq(uint16_t a, uint16_t b)
{
	uint32_t a_tmp = a;
	uint32_t b_tmp = b;
	uint32_t ret = b_tmp - a_tmp;

	ret >>= 31;
	ret -= 1;

	return ret;
}

static inline void vec_cmov(vec * out, vec * in, uint16_t mask)
{
	int i;

	vec m0, m1;

	m0 = vec_set1_16b(mask);
	m1 = ~m0;

	for (i = 0; i < GFBITS; i++)
	{
		out[i] = (in[i] & m0) | (out[i] & m1);
		out[i] = (in[i] & m0) | (out[i] & m1);
	}
}

static inline void interleave(vec *in, int idx0, int idx1, vec *mask, int b)
{
	int s = 1 << b;

	vec x, y;

	x = (in[idx0] & mask[0]) | ((in[idx1] & mask[0]) << s);
	y = ((in[idx0] & mask[1]) >> s) | (in[idx1] & mask[1]);

	in[idx0] = x;
	in[idx1] = y;
}

/* input: in, field elements in bitsliced form */
/* output: out, field elements in non-bitsliced form */
static inline void get_coefs(gf *out, vec *in)
{
	int i, k;

	vec mask[4][2];
	vec buf[16];

	for (i =  0; i < 13; i++) buf[i] = in[i];
	for (i = 13; i < 16; i++) buf[i] = 0;

	mask[0][0] = vec_set1_16b(0x5555);
	mask[0][1] = vec_set1_16b(0xAAAA);
	mask[1][0] = vec_set1_16b(0x3333);
	mask[1][1] = vec_set1_16b(0xCCCC);
	mask[2][0] = vec_set1_16b(0x0F0F);
	mask[2][1] = vec_set1_16b(0xF0F0);
	mask[3][0] = vec_set1_16b(0x00FF);
	mask[3][1] = vec_set1_16b(0xFF00);

	interleave(buf,  0,  8, mask[3], 3);
	interleave(buf,  1,  9, mask[3], 3);
	interleave(buf,  2, 10, mask[3], 3);
	interleave(buf,  3, 11, mask[3], 3);
	interleave(buf,  4, 12, mask[3], 3);
	interleave(buf,  5, 13, mask[3], 3);
	interleave(buf,  6, 14, mask[3], 3);
	interleave(buf,  7, 15, mask[3], 3);

	interleave(buf,  0,  4, mask[2], 2);
	interleave(buf,  1,  5, mask[2], 2);
	interleave(buf,  2,  6, mask[2], 2);
	interleave(buf,  3,  7, mask[2], 2);
	interleave(buf,  8, 12, mask[2], 2);
	interleave(buf,  9, 13, mask[2], 2);
	interleave(buf, 10, 14, mask[2], 2);
	interleave(buf, 11, 15, mask[2], 2);

	interleave(buf,  0,  2, mask[1], 1);
	interleave(buf,  1,  3, mask[1], 1);
	interleave(buf,  4,  6, mask[1], 1);
	interleave(buf,  5,  7, mask[1], 1);
	interleave(buf,  8, 10, mask[1], 1);
	interleave(buf,  9, 11, mask[1], 1);
	interleave(buf, 12, 14, mask[1], 1);
	interleave(buf, 13, 15, mask[1], 1);

	interleave(buf,  0,  1, mask[0], 0);
	interleave(buf,  2,  3, mask[0], 0);
	interleave(buf,  4,  5, mask[0], 0);
	interleave(buf,  6,  7, mask[0], 0);
	interleave(buf,  8,  9, mask[0], 0);
	interleave(buf, 10, 11, mask[0], 0);
	interleave(buf, 12, 13, mask[0], 0);
	interleave(buf, 14, 15, mask[0], 0);

	for (i = 0; i < 16; i++)
	for (k = 0; k <  4; k++)
		out[ k*16 + i ] = (buf[i] >> (k*16)) & GFMASK;
}

static void update(vec in[][GFBITS], const gf e)
{
	int i;
	vec tmp;

	for (i = 0; i < GFBITS; i++)
	{
		tmp = (e >> i) & 1;

		in[0][i] = (in[0][i] >> 1) | (in[1][i] << 63);
		in[1][i] = (in[1][i] >> 1) | (tmp      << 63);
	}
}

static inline gf vec_reduce(vec in[][GFBITS])
{
	int i;
	vec tmp;
	gf ret = 0;

	for (i = GFBITS-1; i >= 0; i--)
	{
		tmp = in[0][i] ^ in[1][i];

		tmp ^= tmp >> 32;
		tmp ^= tmp >> 16;
		tmp ^= tmp >> 8;
		tmp ^= tmp >> 4;
		tmp ^= tmp >> 2;
		tmp ^= tmp >> 1;

		ret <<= 1;
		ret |= tmp & 1;
	}

	return ret;
}

/* input: in, sequence of field elements */
/* output: out, minimal polynomial of in */
static void bm(vec out[][ GFBITS ], vec in[][ GFBITS ])
{
	int i;
	uint16_t N, L;
	uint16_t mask;
	uint64_t one = 1, t;

	vec prod[2][GFBITS];
	vec interval[2][GFBITS];
	vec dd[2][GFBITS], bb[2][GFBITS];
	vec B[2][GFBITS], C[2][GFBITS];
	vec B_tmp[2][GFBITS], C_tmp[2][GFBITS];
	vec v[GFBITS];

	gf d, b, c0 = 1;
	gf coefs[256];

	/* initialization */

	get_coefs(&coefs[  0], in[0]);
	get_coefs(&coefs[ 64], in[1]);
	get_coefs(&coefs[128], in[2]);
	get_coefs(&coefs[192], in[3]);

	C[0][0] = 0;
	C[1][0] = 0;
	B[0][0] = 0;
	B[1][0] = one << 63;

	for (i = 1; i < GFBITS; i++)
		C[0][i] = C[1][i] = B[0][i] = B[1][i] = 0;

	b = 1;
	L = 0;

	/**/

	for (i = 0; i < GFBITS; i++)
		interval[0][i] = interval[1][i] = 0;

	for (N = 0; N < 256; N++)
	{
		vec_mul(prod[0], C[0], interval[0]);
		vec_mul(prod[1], C[1], interval[1]);
		update(interval, coefs[N]);
		d = vec_reduce(prod);

		t = gf_mul2(c0, coefs[N], b);
		d ^= t & 0xFFFFFFFF;

		mask = mask_nonzero(d) & mask_leq(L*2, N);

		for (i = 0; i < GFBITS; i++)
		{
			dd[0][i] = dd[1][i] = vec_setbits((d >> i) & 1);
			bb[0][i] = bb[1][i] = vec_setbits((b >> i) & 1);
		}

		vec_mul(B_tmp[0], dd[0], B[0]);
		vec_mul(B_tmp[1], dd[1], B[1]);
		vec_mul(C_tmp[0], bb[0], C[0]);
		vec_mul(C_tmp[1], bb[1], C[1]);

		vec_cmov(B[0], C[0], mask);
		vec_cmov(B[1], C[1], mask);
		update(B, c0 & mask);

		for (i = 0; i < GFBITS; i++)
		{
			C[0][i] = B_tmp[0][i] ^ C_tmp[0][i];
			C[1][i] = B_tmp[1][i] ^ C_tmp[1][i];
		}

		c0 = t >> 32;
		b = (d & mask) | (b & ~mask);
		L = ((N+1-L) & mask) | (L & ~mask);
	}

	c0 = gf_inv(c0);

	for (i = 0; i < GFBITS; i++)
		v[i] = vec_setbits((c0 >> i) & 1);

	vec_mul(out[0], C[0], v);
	vec_mul(out[1], C[1], v);
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c */
/* This file is for implementing the Nassimi-Sahni algorithm */
/* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */
/* See also https://cr.yp.to/papers/controlbits-20200923.pdf */

/* 20221230 djb: add linker line */

/* linker define controlbitsfrompermutation */

typedef int16_t int16;
typedef int32_t int32;
#define int32_min crypto_int32_min

/* parameters: 1 <= w <= 14; n = 2^w */
/* input: permutation pi of {0,1,...,n-1} */
/* output: (2m-1)n/2 control bits at positions pos,pos+step,... */
/* output position pos is by definition 1&(out[pos/8]>>(pos&7)) */
/* caller must 0-initialize positions first */
/* temp must have space for int32[2*n] */
static void cbrecursion(unsigned char *out,long long pos,long long step,const int16 *pi,long long w,long long n,int32 *temp)
{
#define A temp
#define B (temp+n)
#define q ((int16 *) (temp+n+n/4))
/* q can start anywhere between temp+n and temp+n/2 */

  long long x,i,j,k;

  if (w == 1) {
    out[pos>>3] ^= pi[0]<<(pos&7);
    return;
  }

  for (x = 0;x < n;++x) A[x] = ((pi[x]^1)<<16)|pi[x^1];
  int32_sort(A,n); /* A = (id<<16)+pibar */

  for (x = 0;x < n;++x) {
    int32 Ax = A[x];
    int32 px = Ax&0xffff;
    int32 cx = int32_min(px,x);
    B[x] = (px<<16)|cx;
  }
  /* B = (p<<16)+c */

  for (x = 0;x < n;++x) A[x] = (A[x]<<16)|x; /* A = (pibar<<16)+id */
  int32_sort(A,n); /* A = (id<<16)+pibar^-1 */

  for (x = 0;x < n;++x) A[x] = (A[x]<<16)+(B[x]>>16); /* A = (pibar^(-1)<<16)+pibar */
  int32_sort(A,n); /* A = (id<<16)+pibar^2 */

  if (w <= 10) {
    for (x = 0;x < n;++x) B[x] = ((A[x]&0xffff)<<10)|(B[x]&0x3ff);

    for (i = 1;i < w-1;++i) {
      /* B = (p<<10)+c */

      for (x = 0;x < n;++x) A[x] = ((B[x]&~0x3ff)<<6)|x; /* A = (p<<16)+id */
      int32_sort(A,n); /* A = (id<<16)+p^{-1} */

      for (x = 0;x < n;++x) A[x] = (A[x]<<20)|B[x]; /* A = (p^{-1}<<20)+(p<<10)+c */
      int32_sort(A,n); /* A = (id<<20)+(pp<<10)+cp */

      for (x = 0;x < n;++x) {
        int32 ppcpx = A[x]&0xfffff;
        int32 ppcx = (A[x]&0xffc00)|(B[x]&0x3ff);
        B[x] = int32_min(ppcx,ppcpx);
      }
    }
    for (x = 0;x < n;++x) B[x] &= 0x3ff;
  } else {
    for (x = 0;x < n;++x) B[x] = (A[x]<<16)|(B[x]&0xffff);

    for (i = 1;i < w-1;++i) {
      /* B = (p<<16)+c */

      for (x = 0;x < n;++x) A[x] = (B[x]&~0xffff)|x;
      int32_sort(A,n); /* A = (id<<16)+p^(-1) */

      for (x = 0;x < n;++x) A[x] = (A[x]<<16)|(B[x]&0xffff);
      /* A = p^(-1)<<16+c */

      if (i < w-2) {
        for (x = 0;x < n;++x) B[x] = (A[x]&~0xffff)|(B[x]>>16);
        /* B = (p^(-1)<<16)+p */
        int32_sort(B,n); /* B = (id<<16)+p^(-2) */
        for (x = 0;x < n;++x) B[x] = (B[x]<<16)|(A[x]&0xffff);
        /* B = (p^(-2)<<16)+c */
      }

      int32_sort(A,n);
      /* A = id<<16+cp */
      for (x = 0;x < n;++x) {
        int32 cpx = (B[x]&~0xffff)|(A[x]&0xffff);
        B[x] = int32_min(B[x],cpx);
      }
    }
    for (x = 0;x < n;++x) B[x] &= 0xffff;
  }

  for (x = 0;x < n;++x) A[x] = (((int32)pi[x])<<16)+x;
  int32_sort(A,n); /* A = (id<<16)+pi^(-1) */

  for (j = 0;j < n/2;++j) {
    long long lx = 2*j;
    int32 fj = B[lx]&1; /* f[j] */
    int32 Fx = lx+fj; /* F[x] */
    int32 Fx1 = Fx^1; /* F[x+1] */

    out[pos>>3] ^= fj<<(pos&7);
    pos += step;

    B[lx] = (A[lx]<<16)|Fx;
    B[lx+1] = (A[lx+1]<<16)|Fx1;
  }
  /* B = (pi^(-1)<<16)+F */

  int32_sort(B,n); /* B = (id<<16)+F(pi) */

  pos += (2*w-3)*step*(n/2);

  for (k = 0;k < n/2;++k) {
    long long y = 2*k;
    int32 lk = B[y]&1; /* l[k] */
    int32 Ly = y+lk; /* L[y] */
    int32 Ly1 = Ly^1; /* L[y+1] */

    out[pos>>3] ^= lk<<(pos&7);
    pos += step;

    A[y] = (Ly<<16)|(B[y]&0xffff);
    A[y+1] = (Ly1<<16)|(B[y+1]&0xffff);
  }
  /* A = (L<<16)+F(pi) */

  int32_sort(A,n); /* A = (id<<16)+F(pi(L)) = (id<<16)+M */

  pos -= (2*w-2)*step*(n/2);

  for (j = 0;j < n/2;++j) {
    q[j] = (A[2*j]&0xffff)>>1;
    q[j+n/2] = (A[2*j+1]&0xffff)>>1;
  }

  cbrecursion(out,pos,step*2,q,w-1,n/2,temp);
  cbrecursion(out,pos+step,step*2,q+n/2,w-1,n/2,temp);
}

/* input: p, an array of int16 */
/* input: n, length of p */
/* input: s, meaning that stride-2^s cswaps are performed */
/* input: cb, the control bits */
/* output: the result of apply the control bits to p */
static void layer(int16_t *p, const unsigned char *cb, int s, int n)
{
  int i, j;
  int stride = 1 << s;
  int index = 0;
  int16_t d, m;

  for (i = 0; i < n; i += stride*2)
  {
    for (j = 0; j < stride; j++)
    {
      d = p[ i+j ] ^ p[ i+j+stride ];
      m = (cb[ index >> 3 ] >> (index & 7)) & 1;
      m = -m;
      d &= m;
      p[ i+j ] ^= d;
      p[ i+j+stride ] ^= d;
      index++;
    }
  }
}

/* parameters: 1 <= w <= 14; n = 2^w */
/* input: permutation pi of {0,1,...,n-1} */
/* output: (2m-1)n/2 control bits at positions 0,1,... */
/* output position pos is by definition 1&(out[pos/8]>>(pos&7)) */
static void controlbitsfrompermutation(unsigned char *out,const int16 *pi,long long w,long long n)
{
  int32 temp[2*n];
  int16 pi_test[n], diff;
  int i;
  unsigned char *ptr;

  while (1)
  {
    memset(out,0,(((2*w-1)*n/2)+7)/8);
    cbrecursion(out,0,1,pi,w,n,temp);

    /* check for correctness */

    for (i = 0; i < n; i++)
      pi_test[i] = i;

    ptr = out;
    for (i = 0; i < w; i++)
    {
      layer(pi_test, ptr, i, n);
      ptr += n >> 4;
    }

    for (i = w-2; i >= 0; i--)
    {
      layer(pi_test, ptr, i, n);
      ptr += n >> 4;
    }

    diff = 0;
    for (i = 0; i < n; i++)
      diff |= pi[i] ^ pi_test[i];

    diff = crypto_int16_nonzero_mask(diff);
    crypto_declassify(&diff,sizeof diff);
    if (diff == 0)
      break;
  }
}

#undef A
#undef B
#undef q

/* from libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c */
/*
  This file is for Niederreiter decryption
*/
/* 20221230 djb: add linker lines */

/* linker define decrypt */
/* linker use benes bm fft fft_tr */
/* linker use vec_mul vec_sq vec_inv */




static void scaling(vec out[][GFBITS], vec inv[][GFBITS], const unsigned char *sk, vec *recv)
{
	int i, j;

	vec irr_int[2][ GFBITS ];
	vec eval[128][ GFBITS ];
	vec tmp[ GFBITS ];

	/**/

	irr_load(irr_int, sk);

	fft(eval, irr_int);

	for (i = 0; i < 128; i++)
		vec_sq(eval[i], eval[i]);

	vec_copy(inv[0], eval[0]);

	for (i = 1; i < 128; i++)
		vec_mul(inv[i], inv[i-1], eval[i]);

	vec_inv(tmp, inv[127]);

	for (i = 126; i >= 0; i--)
	{
		vec_mul(inv[i+1], tmp, inv[i]);
		vec_mul(tmp, tmp, eval[i+1]);
	}

	vec_copy(inv[0], tmp);

	/**/

	for (i = 0; i < 128; i++)
	for (j = 0; j < GFBITS; j++)
		out[i][j] = inv[i][j] & recv[i];
}

static void preprocess(vec *recv, const unsigned char *s)
{
	int i;
	unsigned char r[ 1024 ];

	for (i = 0; i < SYND_BYTES; i++)
		r[i] = s[i];

	for (i = SYND_BYTES; i < 1024; i++)
		r[i] = 0;

	for (i = 0; i < 128; i++)
		recv[i] = load8(r + i*8);
}

static void postprocess(unsigned char * e, vec * err)
{
	int i;
	unsigned char error8[ (1 << GFBITS)/8 ];

	for (i = 0; i < 128; i++)
		store8(error8 + i*8, err[i]);

	for (i = 0; i < SYS_N/8; i++)
		e[i] = error8[i];
}

static void scaling_inv(vec out[][GFBITS], vec inv[][GFBITS], vec *recv)
{
	int i, j;

	for (i = 0; i < 128; i++)
	for (j = 0; j < GFBITS; j++)
		out[i][j] = inv[i][j] & recv[i];
}

static int weight_check(unsigned char * e, vec * error)
{
	int i;
	uint16_t w0 = 0;
	uint16_t w1 = 0;
	uint16_t check;

	for (i = 0; i < (1 << GFBITS); i++)
		w0 += (error[i/64] >> (i%64)) & 1;

	for (i = 0; i < SYS_N; i++)
		w1 += (e[i/8] >> (i%8)) & 1;

	check = (w0 ^ SYS_T) | (w1 ^ SYS_T);
	check -= 1;
	check >>= 15;

	return check;
}

static uint16_t synd_cmp(vec s0[][ GFBITS ] , vec s1[][ GFBITS ])
{
	int i, j;
	vec diff = 0;

	for (i = 0; i < 4; i++)
	for (j = 0; j < GFBITS; j++)
		diff |= (s0[i][j] ^ s1[i][j]);

	return vec_testz(diff);
}

/* Niederreiter decryption with the Berlekamp decoder */
/* intput: sk, secret key */
/*         s, ciphertext (syndrome) */
/* output: e, error vector */
/* return: 0 for success; 1 for failure */
static int decrypt(unsigned char *e, const unsigned char *sk, const unsigned char *s)
{
	int i;

	uint16_t check_synd;
	uint16_t check_weight;

	vec inv[ 128 ][ GFBITS ];
	vec scaled[ 128 ][ GFBITS ];
	vec eval[ 128 ][ GFBITS ];

	vec error[ 128 ];

	vec s_priv[ 4 ][ GFBITS ];
	vec s_priv_cmp[ 4 ][ GFBITS ];
	vec locator[2][ GFBITS ];

	vec recv[ 128 ];
	vec allone;

	/* Berlekamp decoder */

	preprocess(recv, s);

	benes(recv, sk + IRR_BYTES, 1);
	scaling(scaled, inv, sk, recv);
	fft_tr(s_priv, scaled);
	bm(locator, s_priv);

	fft(eval, locator);

	/* reencryption and weight check */

	allone = vec_setbits(1);

	for (i = 0; i < 128; i++)
	{
		error[i] = vec_or_reduce(eval[i]);
		error[i] ^= allone;
	}

	scaling_inv(scaled, inv, error);
	fft_tr(s_priv_cmp, scaled);

	check_synd = synd_cmp(s_priv, s_priv_cmp);

	/**/

	benes(error, sk + IRR_BYTES, 0);

	postprocess(e, error);

	check_weight = weight_check(e, error);

#ifdef KAT
  {
    int k;
    printf("decrypt e: positions");
    for (k = 0;k < SYS_N;++k)
      if (e[k/8] & (1 << (k&7)))
        printf(" %d",k);
    printf("\n");
  }
#endif

	return 1 - (check_synd & check_weight);
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c */
/* 20230102 djb: rename encrypt() as pke_encrypt() */
/* 20221231 djb: move encrypt.h last for macos portability; tnx thom wiggers */
/* 20221230 djb: add linker line */

/* linker define pke_encrypt */

/*
  This file is for Niederreiter encryption
*/





static inline crypto_uint16 uint16_is_smaller_declassify(uint16_t t,uint16_t u)
{
  crypto_uint16 mask = crypto_uint16_smaller_mask(t,u);
  crypto_declassify(&mask,sizeof mask);
  return mask;
}

static inline crypto_uint32 uint32_is_equal_declassify(uint32_t t,uint32_t u)
{
  crypto_uint32 mask = crypto_uint32_equal_mask(t,u);
  crypto_declassify(&mask,sizeof mask);
  return mask;
}

/* output: e, an error vector of weight t */
static void gen_e(unsigned char *e)
{
	int i, j, eq, count;

	union
	{
		uint16_t nums[ SYS_T*2 ];
		unsigned char bytes[ SYS_T*2 * sizeof(uint16_t) ];
	} buf;

	uint16_t ind[ SYS_T ];
	uint64_t e_int[ (SYS_N+63)/64 ];
	uint64_t one = 1;
	uint64_t mask;
	uint64_t val[ SYS_T ];

	while (1)
	{
		randombytes(buf.bytes, sizeof(buf));

		for (i = 0; i < SYS_T*2; i++)
			buf.nums[i] = load_gf(buf.bytes + i*2);

		/* moving and counting indices in the correct range */

		count = 0;
		for (i = 0; i < SYS_T*2 && count < SYS_T; i++)
			if (uint16_is_smaller_declassify(buf.nums[i],SYS_N))
				ind[ count++ ] = buf.nums[i];

		if (count < SYS_T) continue;

		/* check for repetition */

		uint16_sort(ind, SYS_T);

		eq = 0;
		for (i = 1; i < SYS_T; i++)
			if (uint32_is_equal_declassify(ind[i-1],ind[i]))
				eq = 1;

		if (eq == 0)
			break;
	}

	for (j = 0; j < SYS_T; j++)
		val[j] = one << (ind[j] & 63);

	for (i = 0; i < (SYS_N+63)/64; i++)
	{
		e_int[i] = 0;

		for (j = 0; j < SYS_T; j++)
		{
			mask = i ^ (ind[j] >> 6);
			mask -= 1;
			mask >>= 63;
			mask = -mask;

			e_int[i] |= val[j] & mask;
		}
	}

	for (i = 0; i < (SYS_N+63)/64 - 1; i++)
		{ store8(e, e_int[i]); e += 8; }

	for (j = 0; j < (SYS_N % 64); j+=8)
		e[ j/8 ] = (e_int[i] >> j) & 0xFF;
}

/* input: public key pk, error vector e */
/* output: syndrome s */
static void syndrome(unsigned char *s, const unsigned char *pk, unsigned char *e)
{
	uint64_t b;

	const uint64_t *pk_ptr;
	const uint64_t *e_ptr = ((uint64_t *) (e + SYND_BYTES));

	int i, j;

	/**/

	for (i = 0; i < SYND_BYTES; i++)
		s[i] = e[i];

	for (i = 0; i < PK_NROWS; i++)
	{
		pk_ptr = ((uint64_t *) (pk + PK_ROW_BYTES * i));

		b = 0;
		for (j = 0; j < PK_NCOLS/64; j++)
			b ^= pk_ptr[j] & e_ptr[j];

		b ^= ((uint32_t *) &pk_ptr[j])[0] & ((uint32_t *) &e_ptr[j])[0];

		b ^= b >> 32;
		b ^= b >> 16;
		b ^= b >> 8;
		b ^= b >> 4;
		b ^= b >> 2;
		b ^= b >> 1;
		b &= 1;

		s[ i/8 ] ^= (b << (i%8));
	}
}

/* input: public key pk */
/* output: error vector e, syndrome s */
static void pke_encrypt(unsigned char *s, const unsigned char *pk, unsigned char *e)
{
	gen_e(e);

#ifdef KAT
  {
    int k;
    printf("encrypt e: positions");
    for (k = 0;k < SYS_N;++k)
      if (e[k/8] & (1 << (k&7)))
        printf(" %d",k);
    printf("\n");
  }
#endif

	syndrome(s, pk, e);
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c */
/* linker define fft_consts */


const vec fft_consts[128][GFBITS] = {
{ 0x6969969669699696, 0x9966669966999966, 0x9966669966999966, 0xFF0000FF00FFFF00, 0xCC3333CCCC3333CC, 0x9966669966999966, 0x6666666666666666, 0xA55AA55AA55AA55A, 0xCCCC33333333CCCC, 0x5A5A5A5A5A5A5A5A, 0x55AAAA55AA5555AA, 0x0FF0F00FF00F0FF0, 0x5AA55AA5A55AA55A }, { 0x6969969669699696, 0x9966669966999966, 0x9966669966999966, 0xFF0000FF00FFFF00, 0xCC3333CCCC3333CC, 0x9966669966999966, 0x6666666666666666, 0xA55AA55AA55AA55A, 0xCCCC33333333CCCC, 0x5A5A5A5A5A5A5A5A, 0x55AAAA55AA5555AA, 0x0FF0F00FF00F0FF0, 0x5AA55AA5A55AA55A }, { 0xA55A5AA55AA5A55A, 0x6969696996969696, 0x5AA55AA5A55AA55A, 0x9999999966666666, 0x3C3CC3C3C3C33C3C, 0xFFFF0000FFFF0000, 0x0000000000000000, 0xCC33CC3333CC33CC, 0x0000000000000000, 0x3C3C3C3C3C3C3C3C, 0xAA5555AAAA5555AA, 0xC33C3CC33CC3C33C, 0x00FFFF0000FFFF00 }, { 0xA55A5AA55AA5A55A, 0x6969696996969696, 0x5AA55AA5A55AA55A, 0x6666666699999999, 0xC3C33C3C3C3CC3C3, 0x0000FFFF0000FFFF, 0x0000000000000000, 0x33CC33CCCC33CC33, 0x0000000000000000, 0x3C3C3C3C3C3C3C3C, 0xAA5555AAAA5555AA, 0xC33C3CC33CC3C33C, 0xFF0000FFFF0000FF }, { 0xFFFFFFFF00000000, 0xA5A5A5A55A5A5A5A, 0x0FF0F00FF00F0FF0, 0x9669966969966996, 0x0000FFFFFFFF0000, 0x33333333CCCCCCCC, 0xA55A5AA55AA5A55A, 0x00FFFF0000FFFF00, 0x0000000000000000, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAA55555555AAAA }, { 0xFFFFFFFF00000000, 0xA5A5A5A55A5A5A5A, 0x0FF0F00FF00F0FF0, 0x6996699696699669, 0xFFFF00000000FFFF, 0x33333333CCCCCCCC, 0x5AA5A55AA55A5AA5, 0xFF0000FFFF0000FF, 0xFFFFFFFFFFFFFFFF, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0x5555AAAAAAAA5555 }, { 0xFFFFFFFF00000000, 0x5A5A5A5AA5A5A5A5, 0xF00F0FF00FF0F00F, 0x6996699696699669, 0x0000FFFFFFFF0000, 0x33333333CCCCCCCC, 0x5AA5A55AA55A5AA5, 0xFF0000FFFF0000FF, 0xFFFFFFFFFFFFFFFF, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAA55555555AAAA }, { 0xFFFFFFFF00000000, 0x5A5A5A5AA5A5A5A5, 0xF00F0FF00FF0F00F, 0x9669966969966996, 0xFFFF00000000FFFF, 0x33333333CCCCCCCC, 0xA55A5AA55AA5A55A, 0x00FFFF0000FFFF00, 0x0000000000000000, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0x5555AAAAAAAA5555 }, { 0xC33C3CC33CC3C33C, 0x9966669966999966, 0x9966996699669966, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x9966996699669966, 0x5AA5A55A5AA5A55A, 0xC3C3C3C33C3C3C3C, 0x3CC33CC3C33CC33C, 0x3333CCCC3333CCCC, 0x9999999966666666, 0xC33CC33CC33CC33C, 0x6666999999996666 }, { 0x3CC3C33CC33C3CC3, 0x6699996699666699, 0x6699669966996699, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x9966996699669966, 0xA55A5AA5A55A5AA5, 0xC3C3C3C33C3C3C3C, 0x3CC33CC3C33CC33C, 0x3333CCCC3333CCCC, 0x6666666699999999, 0x3CC33CC33CC33CC3, 0x9999666666669999 }, { 0xC33C3CC33CC3C33C, 0x9966669966999966, 0x6699669966996699, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x6699669966996699, 0x5AA5A55A5AA5A55A, 0x3C3C3C3CC3C3C3C3, 0xC33CC33C3CC33CC3, 0xCCCC3333CCCC3333, 0x6666666699999999, 0xC33CC33CC33CC33C, 0x9999666666669999 }, { 0x3CC3C33CC33C3CC3, 0x6699996699666699, 0x9966996699669966, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x6699669966996699, 0xA55A5AA5A55A5AA5, 0x3C3C3C3CC3C3C3C3, 0xC33CC33C3CC33CC3, 0xCCCC3333CCCC3333, 0x9999999966666666, 0x3CC33CC33CC33CC3, 0x6666999999996666 }, { 0xC33C3CC33CC3C33C, 0x6699996699666699, 0x6699669966996699, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x9966996699669966, 0x5AA5A55A5AA5A55A, 0xC3C3C3C33C3C3C3C, 0xC33CC33C3CC33CC3, 0x3333CCCC3333CCCC, 0x9999999966666666, 0xC33CC33CC33CC33C, 0x6666999999996666 }, { 0x3CC3C33CC33C3CC3, 0x9966669966999966, 0x9966996699669966, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x9966996699669966, 0xA55A5AA5A55A5AA5, 0xC3C3C3C33C3C3C3C, 0xC33CC33C3CC33CC3, 0x3333CCCC3333CCCC, 0x6666666699999999, 0x3CC33CC33CC33CC3, 0x9999666666669999 }, { 0xC33C3CC33CC3C33C, 0x6699996699666699, 0x9966996699669966, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x6699669966996699, 0x5AA5A55A5AA5A55A, 0x3C3C3C3CC3C3C3C3, 0x3CC33CC3C33CC33C, 0xCCCC3333CCCC3333, 0x6666666699999999, 0xC33CC33CC33CC33C, 0x9999666666669999 }, { 0x3CC3C33CC33C3CC3, 0x9966669966999966, 0x6699669966996699, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x6699669966996699, 0xA55A5AA5A55A5AA5, 0x3C3C3C3CC3C3C3C3, 0x3CC33CC3C33CC33C, 0xCCCC3333CCCC3333, 0x9999999966666666, 0x3CC33CC33CC33CC3, 0x6666999999996666 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA },
};

/* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c */
/* linker define fft_powers */


const vec fft_powers[128][GFBITS] = {
{ 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }
};

/* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c */
/* linker define fft_scalars_2x */


const vec fft_scalars_2x[5][2][GFBITS] = {
{{ 0X3C3CF30C0000C003, 0X0CCCC3F333C0000C, 0X03C33F33FCC0C03C, 0X0003000F3C03C0C0, 0XF33FF33030CF03F0, 0X0CF0303300F0CCC0, 0XFF3F0C0CC0FF3CC0, 0XCF3CF0FF003FC000, 0XC00FF3CF0303F300, 0X3CCC0CC00CF0CC00, 0XF30FFC3C3FCCFC00, 0X3F0FC3F0CCF0C000, 0X3000FF33CCF0F000 }, { 0X0C0F0FCF0F0CF330, 0XF0000FC33C3CCF3C, 0X3C0F3F00C3C300FC, 0X3C33CCC0F0F3CC30, 0XC0CFFFFFCCCC30CC, 0X3FC3F3CCFFFC033F, 0XFC3030CCCCC0CFCF, 0X0FCF0C00CCF333C3, 0XCFFCF33000CFF030, 0X00CFFCC330F30FCC, 0X3CCC3FCCC0F3FFF3, 0XF00F0C3FC003C0FF, 0X330CCFCC03C0FC33 }}, {{ 0X0F0F0FF0F000000F, 0X00FFFFFFFF0000F0, 0XFFFF00FF00000F00, 0XFFF000F00F0FF000, 0XFFF0000F0FF000F0, 0X00FF000FFF000000, 0XFF0F0FFF0F0FF000, 0X0FFF0000000F0000, 0X00F000F0FFF00F00, 0X00F00FF00F00F000, 0XFFF000F000F00000, 0X00F00F000FF00000, 0X0000FF0F0000F000 }, { 0XF0FFFFFFF0F00F00, 0X00FFF0FFFF0000FF, 0X00FF00000F0F0FFF, 0XF000F0000F00FF0F, 0XFF000000FFF00000, 0XF0FF000FF00F0FF0, 0X0F0F0F00FF000F0F, 0X0F0F00F0F0F0F000, 0X00F00F00F00F000F, 0X00F0F0F00000FFF0, 0XFFFFFF0FF00F0FFF, 0X0F0FFFF00FFFFFFF, 0XFFFF0F0FFF0FFF00 }}, {{ 0X00FF0000000000FF, 0XFFFFFFFFFF00FF00, 0XFF0000FF00FF0000, 0XFFFF000000FF0000, 0XFF00000000FF0000, 0X00FFFFFFFF000000, 0XFF0000FFFFFF0000, 0XFF00FF00FFFF0000, 0X00FFFFFFFF00FF00, 0XFFFF000000000000, 0X00FF0000FF000000, 0XFF00FF00FF000000, 0X00FF00FFFF000000 }, { 0X00FF00FF00FF0000, 0XFF00FFFF000000FF, 0X0000FFFF000000FF, 0X00FFFF00FF000000, 0XFFFFFF0000FF00FF, 0X0000FFFF00FFFF00, 0XFF00FF0000FFFF00, 0X00000000FFFFFFFF, 0X0000FF0000000000, 0XFF00FFFF00FFFF00, 0X00FFFF00000000FF, 0X0000FF00FF00FFFF, 0XFF0000FFFFFF0000 }}, {{ 0X000000000000FFFF, 0XFFFFFFFFFFFF0000, 0X0000000000000000, 0XFFFF0000FFFF0000, 0XFFFFFFFFFFFF0000, 0X0000FFFF00000000, 0X0000FFFFFFFF0000, 0XFFFF0000FFFF0000, 0X0000FFFF00000000, 0XFFFF000000000000, 0XFFFF000000000000, 0XFFFF000000000000, 0XFFFFFFFF00000000 }, { 0X0000FFFF00000000, 0XFFFFFFFF0000FFFF, 0X00000000FFFFFFFF, 0X0000000000000000, 0X0000FFFF00000000, 0XFFFF0000FFFF0000, 0X0000FFFFFFFF0000, 0X0000FFFF0000FFFF, 0XFFFFFFFF0000FFFF, 0X00000000FFFF0000, 0XFFFF0000FFFFFFFF, 0XFFFF0000FFFFFFFF, 0X0000000000000000 }}, {{ 0X00000000FFFFFFFF, 0X0000000000000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFF00000000, 0XFFFFFFFF00000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0X0000000000000000, 0X0000000000000000, 0XFFFFFFFF00000000 }, { 0X0000000000000000, 0XFFFFFFFFFFFFFFFF, 0X0000000000000000, 0X0000000000000000, 0X00000000FFFFFFFF, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFFFFFFFFFF, 0X00000000FFFFFFFF, 0XFFFFFFFF00000000, 0XFFFFFFFFFFFFFFFF, 0XFFFFFFFFFFFFFFFF, 0XFFFFFFFF00000000 }}
};

/* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c */
/* linker define fft_scalars_4x */


const vec fft_scalars_4x[6][4][GFBITS] = {
{{ 0x3C3CF30C0000C003, 0x0CCCC3F333C0000C, 0x03C33F33FCC0C03C, 0x0003000F3C03C0C0, 0xF33FF33030CF03F0, 0x0CF0303300F0CCC0, 0xFF3F0C0CC0FF3CC0, 0xCF3CF0FF003FC000, 0xC00FF3CF0303F300, 0x3CCC0CC00CF0CC00, 0xF30FFC3C3FCCFC00, 0x3F0FC3F0CCF0C000, 0x3000FF33CCF0F000 }, { 0x0C0F0FCF0F0CF330, 0xF0000FC33C3CCF3C, 0x3C0F3F00C3C300FC, 0x3C33CCC0F0F3CC30, 0xC0CFFFFFCCCC30CC, 0x3FC3F3CCFFFC033F, 0xFC3030CCCCC0CFCF, 0x0FCF0C00CCF333C3, 0xCFFCF33000CFF030, 0x00CFFCC330F30FCC, 0x3CCC3FCCC0F3FFF3, 0xF00F0C3FC003C0FF, 0x330CCFCC03C0FC33 }, { 0xF0F30C33CF03F03F, 0x00F30FC00C3300FF, 0xF3CC3CF3F3FCF33F, 0x3C0FC0FC303C3F3C, 0xFC30CF303F3FF00F, 0x33300C0CC3300CF3, 0x3C030CF3F03FF3F3, 0x3CCC03FCCC3FFC03, 0x033C3C3CF0003FC3, 0xFFC0FF00F0FF0F03, 0xF3F30CF003FCC303, 0x30CFCFC3CC0F3000, 0x0CF30CCF3FCFCC0F }, { 0x3F30CC0C000F3FCC, 0xFC3CF030FC3FFF03, 0x33FFFCFF0CCF3CC3, 0x003CFF33C3CC30CF, 0xCFF3CF33C00F3003, 0x00F3CC0CF3003CCF, 0x3C000CFCCC3C3333, 0xF3CF03C0FCF03FF0, 0x3F3C3CF0C330330C, 0x33CCFCC0FF0033F0, 0x33C300C0F0C003F3, 0x003FF0003F00C00C, 0xCFF3C3033F030FFF }}, {{ 0x0F0F0FF0F000000F, 0x00FFFFFFFF0000F0, 0xFFFF00FF00000F00, 0xFFF000F00F0FF000, 0xFFF0000F0FF000F0, 0x00FF000FFF000000, 0xFF0F0FFF0F0FF000, 0x0FFF0000000F0000, 0x00F000F0FFF00F00, 0x00F00FF00F00F000, 0xFFF000F000F00000, 0x00F00F000FF00000, 0x0000FF0F0000F000 }, { 0xF0FFFFFFF0F00F00, 0x00FFF0FFFF0000FF, 0x00FF00000F0F0FFF, 0xF000F0000F00FF0F, 0xFF000000FFF00000, 0xF0FF000FF00F0FF0, 0x0F0F0F00FF000F0F, 0x0F0F00F0F0F0F000, 0x00F00F00F00F000F, 0x00F0F0F00000FFF0, 0xFFFFFF0FF00F0FFF, 0x0F0FFFF00FFFFFFF, 0xFFFF0F0FFF0FFF00 }, { 0x0F0F00FF0FF0FFFF, 0xF000F0F00F00FF0F, 0x000FFFF0FFF0FF0F, 0x00F00FFF00000FF0, 0xFFFFF0000FFFF00F, 0xFFF0FFF0000FFFF0, 0xF0F0F0000F0F0F00, 0x00F000F0F00FFF00, 0xF0FF0F0FFF00F0FF, 0xF0FF0FFFF0F0F0FF, 0x00FFFFFFFFFFFFF0, 0x00FFF0F0FF000F0F, 0x000FFFF0000FFF00 }, { 0xFF0F0F00F000F0FF, 0x0FFFFFFFFF00000F, 0xF0FFFF000F00F0FF, 0x0F0000F00FFF0FFF, 0x0F0F0F00FF0F000F, 0x000F0F0FFFF0F000, 0xF0FFFF0F00F0FF0F, 0x0F0F000F0F00F0FF, 0x0000F0FF00FF0F0F, 0x00FFFF0FF0FFF0F0, 0x0000000F00F0FFF0, 0xF0F00000FF00F0F0, 0x0F0F0FFFFFFFFFFF }}, {{ 0x00FF0000000000FF, 0xFFFFFFFFFF00FF00, 0xFF0000FF00FF0000, 0xFFFF000000FF0000, 0xFF00000000FF0000, 0x00FFFFFFFF000000, 0xFF0000FFFFFF0000, 0xFF00FF00FFFF0000, 0x00FFFFFFFF00FF00, 0xFFFF000000000000, 0x00FF0000FF000000, 0xFF00FF00FF000000, 0x00FF00FFFF000000 }, { 0x00FF00FF00FF0000, 0xFF00FFFF000000FF, 0x0000FFFF000000FF, 0x00FFFF00FF000000, 0xFFFFFF0000FF00FF, 0x0000FFFF00FFFF00, 0xFF00FF0000FFFF00, 0x00000000FFFFFFFF, 0x0000FF0000000000, 0xFF00FFFF00FFFF00, 0x00FFFF00000000FF, 0x0000FF00FF00FFFF, 0xFF0000FFFFFF0000 }, { 0xFFFF00FF00FF00FF, 0x00FFFF000000FF00, 0xFFFF00FFFFFFFF00, 0x0000FFFF00FFFFFF, 0x00FF0000FF0000FF, 0xFFFF0000FF00FFFF, 0xFF000000FFFFFF00, 0x000000000000FFFF, 0xFF00FF00FFFF0000, 0xFFFF00FFFF00FFFF, 0xFFFFFFFFFF00FF00, 0xFFFF00FFFF0000FF, 0x0000FF00000000FF }, { 0xFF0000FFFFFF00FF, 0xFFFF0000FFFFFFFF, 0xFFFF000000FFFFFF, 0x00FFFF00FF0000FF, 0xFFFFFF00FFFFFF00, 0x00FFFF00FFFF00FF, 0x0000FFFF00FF0000, 0x000000FFFF000000, 0xFF00FF0000FF00FF, 0x00FF0000000000FF, 0xFF00FFFF00FF00FF, 0xFFFFFFFFFFFFFFFF, 0x0000FF000000FFFF }}, {{ 0x000000000000FFFF, 0xFFFFFFFFFFFF0000, 0x0000000000000000, 0xFFFF0000FFFF0000, 0xFFFFFFFFFFFF0000, 0x0000FFFF00000000, 0x0000FFFFFFFF0000, 0xFFFF0000FFFF0000, 0x0000FFFF00000000, 0xFFFF000000000000, 0xFFFF000000000000, 0xFFFF000000000000, 0xFFFFFFFF00000000 }, { 0x0000FFFF00000000, 0xFFFFFFFF0000FFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0x0000FFFF00000000, 0xFFFF0000FFFF0000, 0x0000FFFFFFFF0000, 0x0000FFFF0000FFFF, 0xFFFFFFFF0000FFFF, 0x00000000FFFF0000, 0xFFFF0000FFFFFFFF, 0xFFFF0000FFFFFFFF, 0x0000000000000000 }, { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x0000FFFFFFFFFFFF, 0x0000FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x000000000000FFFF, 0x000000000000FFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFF0000FFFF, 0xFFFF0000FFFFFFFF }, { 0x0000FFFFFFFFFFFF, 0x0000FFFF0000FFFF, 0x0000FFFFFFFF0000, 0xFFFF0000FFFFFFFF, 0x00000000FFFF0000, 0xFFFF00000000FFFF, 0x0000FFFF0000FFFF, 0xFFFF00000000FFFF, 0x0000FFFF0000FFFF, 0x0000FFFF00000000, 0xFFFFFFFF00000000, 0x0000FFFFFFFF0000, 0x0000FFFFFFFFFFFF }}, {{ 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000 }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000 }, { 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }, { 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000 }}, {{ 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000 }, { 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF }},
};

/* from libmceliece-20230612/crypto_kem/6688128f/vec/fft.c */
/*
  This file is for implementing the Gao-Mateer FFT, see
  http://www.math.clemson.edu/~sgao/papers/GM10.pdf

  For the implementation strategy, see
  https://eprint.iacr.org/2017/793.pdf
*/
/* 20221230 djb: split these arrays into separate .c files */
/* 20221230 djb: rename powers array as fft_powers */
/* 20221230 djb: rename consts array as fft_consts */
/* 20221230 djb: rename s array as fft_scalars_2x */
/* 20221230 djb: add linker lines */

/* linker define fft */
/* linker use vec_mul */
/* linker use fft_scalars_2x fft_consts fft_powers */




/* input: in, polynomial in bitsliced form */
/* output: in, result of applying the radix conversions on in */
static void radix_conversions(vec in[][GFBITS])
{
	int i, j, k;

	const vec mask[5][2] =
	{
		{0x8888888888888888, 0x4444444444444444},
		{0xC0C0C0C0C0C0C0C0, 0x3030303030303030},
		{0xF000F000F000F000, 0x0F000F000F000F00},
		{0xFF000000FF000000, 0x00FF000000FF0000},
		{0xFFFF000000000000, 0x0000FFFF00000000}
	};

	for (j = 0; j <= 5; j++)
	{
		for (i = 0; i < GFBITS; i++)
		{
			in[1][i] ^= in[1][i] >> 32;
			in[0][i] ^= in[1][i] << 32;
		}

		for (i = 0; i < GFBITS; i++)
		for (k = 4; k >= j; k--)
		{
			in[0][i] ^= (in[0][i] & mask[k][0]) >> (1 << k);
			in[0][i] ^= (in[0][i] & mask[k][1]) >> (1 << k);
			in[1][i] ^= (in[1][i] & mask[k][0]) >> (1 << k);
			in[1][i] ^= (in[1][i] & mask[k][1]) >> (1 << k);
		}

		if (j < 5)
		{
			vec_mul(in[0], in[0], fft_scalars_2x[j][0]);
			vec_mul(in[1], in[1], fft_scalars_2x[j][1]);
		}
	}
}

/* input: in, result of applying the radix conversions to the input polynomial */
/* output: out, evaluation results (by applying the FFT butterflies) */
static void butterflies(vec out[][ GFBITS ], vec in[][ GFBITS ])
{
	int i, j, k, s, b;

	vec tmp[ GFBITS ];
	vec pre[8][ GFBITS ];
	vec buf[128];

	uint64_t consts_ptr = 2;

	const unsigned char reversal[128] =
	{
	  0, 64, 32, 96, 16, 80, 48, 112,
	  8, 72, 40, 104, 24, 88, 56, 120,
	  4, 68, 36, 100, 20, 84, 52, 116,
	  12, 76, 44, 108, 28, 92, 60, 124,
	  2, 66, 34, 98, 18, 82, 50, 114,
	  10, 74, 42, 106, 26, 90, 58, 122,
	  6, 70, 38, 102, 22, 86, 54, 118,
	  14, 78, 46, 110, 30, 94, 62, 126,
	  1, 65, 33, 97, 17, 81, 49, 113,
	  9, 73, 41, 105, 25, 89, 57, 121,
	  5, 69, 37, 101, 21, 85, 53, 117,
	  13, 77, 45, 109, 29, 93, 61, 125,
	  3, 67, 35, 99, 19, 83, 51, 115,
	  11, 75, 43, 107, 27, 91, 59, 123,
	  7, 71, 39, 103, 23, 87, 55, 119,
	  15, 79, 47, 111, 31, 95, 63, 127
	};

	const uint16_t beta[7] = {2522, 7827, 7801, 8035, 6897, 8167, 3476};

	/**/

	for (i = 0; i < 7; i++)
	{
		for (j = 0; j < GFBITS; j++)
		{
			pre[i][j] = (beta[i] >> j) & 1;
			pre[i][j] = -pre[i][j];
		}

		vec_mul(pre[i], in[1], pre[i]);
	}

	for (i = 0; i < GFBITS; i++)
	{
		buf[0] = in[0][i];

		buf[1] = buf[0] ^ pre[0][i];      buf[32] = in[0][i] ^ pre[5][i];
		buf[3] = buf[1] ^ pre[1][i];      buf[96] = buf[32] ^ pre[6][i];
                                              buf[97] = buf[96] ^ pre[0][i];
		buf[2] = in[0][i] ^ pre[1][i];  buf[99] = buf[97] ^ pre[1][i];
		buf[6] = buf[2] ^ pre[2][i];      buf[98] = buf[99] ^ pre[0][i];
		buf[7] = buf[6] ^ pre[0][i];      buf[102] = buf[98] ^ pre[2][i];
		buf[5] = buf[7] ^ pre[1][i];      buf[103] = buf[102] ^ pre[0][i];
                                              buf[101] = buf[103] ^ pre[1][i];
		buf[4] = in[0][i] ^ pre[2][i];  buf[100] = buf[101] ^ pre[0][i];
		buf[12] = buf[4] ^ pre[3][i];     buf[108] = buf[100] ^ pre[3][i];
		buf[13] = buf[12] ^ pre[0][i];    buf[109] = buf[108] ^ pre[0][i];
		buf[15] = buf[13] ^ pre[1][i];    buf[111] = buf[109] ^ pre[1][i];
		buf[14] = buf[15] ^ pre[0][i];    buf[110] = buf[111] ^ pre[0][i];
		buf[10] = buf[14] ^ pre[2][i];    buf[106] = buf[110] ^ pre[2][i];
		buf[11] = buf[10] ^ pre[0][i];    buf[107] = buf[106] ^ pre[0][i];
		buf[9] = buf[11] ^ pre[1][i];     buf[105] = buf[107] ^ pre[1][i];
                                              buf[104] = buf[105] ^ pre[0][i];
		buf[8] = in[0][i] ^ pre[3][i];  buf[120] = buf[104] ^ pre[4][i];
		buf[24] = buf[8] ^ pre[4][i];     buf[121] = buf[120] ^ pre[0][i];
		buf[25] = buf[24] ^ pre[0][i];    buf[123] = buf[121] ^ pre[1][i];
		buf[27] = buf[25] ^ pre[1][i];    buf[122] = buf[123] ^ pre[0][i];
		buf[26] = buf[27] ^ pre[0][i];    buf[126] = buf[122] ^ pre[2][i];
		buf[30] = buf[26] ^ pre[2][i];    buf[127] = buf[126] ^ pre[0][i];
		buf[31] = buf[30] ^ pre[0][i];    buf[125] = buf[127] ^ pre[1][i];
		buf[29] = buf[31] ^ pre[1][i];    buf[124] = buf[125] ^ pre[0][i];
		buf[28] = buf[29] ^ pre[0][i];    buf[116] = buf[124] ^ pre[3][i];
		buf[20] = buf[28] ^ pre[3][i];    buf[117] = buf[116] ^ pre[0][i];
		buf[21] = buf[20] ^ pre[0][i];    buf[119] = buf[117] ^ pre[1][i];
		buf[23] = buf[21] ^ pre[1][i];    buf[118] = buf[119] ^ pre[0][i];
		buf[22] = buf[23] ^ pre[0][i];    buf[114] = buf[118] ^ pre[2][i];
		buf[18] = buf[22] ^ pre[2][i];    buf[115] = buf[114] ^ pre[0][i];
		buf[19] = buf[18] ^ pre[0][i];    buf[113] = buf[115] ^ pre[1][i];
		buf[17] = buf[19] ^ pre[1][i];    buf[112] = buf[113] ^ pre[0][i];
                                              buf[80] = buf[112] ^ pre[5][i];
		buf[16] = in[0][i] ^ pre[4][i]; buf[81] = buf[80] ^ pre[0][i];
		buf[48] = buf[16] ^ pre[5][i];    buf[83] = buf[81] ^ pre[1][i];
		buf[49] = buf[48] ^ pre[0][i];    buf[82] = buf[83] ^ pre[0][i];
		buf[51] = buf[49] ^ pre[1][i];    buf[86] = buf[82] ^ pre[2][i];
		buf[50] = buf[51] ^ pre[0][i];    buf[87] = buf[86] ^ pre[0][i];
		buf[54] = buf[50] ^ pre[2][i];    buf[85] = buf[87] ^ pre[1][i];
		buf[55] = buf[54] ^ pre[0][i];    buf[84] = buf[85] ^ pre[0][i];
		buf[53] = buf[55] ^ pre[1][i];    buf[92] = buf[84] ^ pre[3][i];
		buf[52] = buf[53] ^ pre[0][i];    buf[93] = buf[92] ^ pre[0][i];
		buf[60] = buf[52] ^ pre[3][i];    buf[95] = buf[93] ^ pre[1][i];
		buf[61] = buf[60] ^ pre[0][i];    buf[94] = buf[95] ^ pre[0][i];
		buf[63] = buf[61] ^ pre[1][i];    buf[90] = buf[94] ^ pre[2][i];
		buf[62] = buf[63] ^ pre[0][i];    buf[91] = buf[90] ^ pre[0][i];
		buf[58] = buf[62] ^ pre[2][i];    buf[89] = buf[91] ^ pre[1][i];
		buf[59] = buf[58] ^ pre[0][i];    buf[88] = buf[89] ^ pre[0][i];
		buf[57] = buf[59] ^ pre[1][i];    buf[72] = buf[88] ^ pre[4][i];
		buf[56] = buf[57] ^ pre[0][i];    buf[73] = buf[72] ^ pre[0][i];
		buf[40] = buf[56] ^ pre[4][i];    buf[75] = buf[73] ^ pre[1][i];
		buf[41] = buf[40] ^ pre[0][i];    buf[74] = buf[75] ^ pre[0][i];
		buf[43] = buf[41] ^ pre[1][i];    buf[78] = buf[74] ^ pre[2][i];
		buf[42] = buf[43] ^ pre[0][i];    buf[79] = buf[78] ^ pre[0][i];
		buf[46] = buf[42] ^ pre[2][i];    buf[77] = buf[79] ^ pre[1][i];
		buf[47] = buf[46] ^ pre[0][i];    buf[76] = buf[77] ^ pre[0][i];
		buf[45] = buf[47] ^ pre[1][i];    buf[68] = buf[76] ^ pre[3][i];
		buf[44] = buf[45] ^ pre[0][i];    buf[69] = buf[68] ^ pre[0][i];
		buf[36] = buf[44] ^ pre[3][i];    buf[71] = buf[69] ^ pre[1][i];
		buf[37] = buf[36] ^ pre[0][i];    buf[70] = buf[71] ^ pre[0][i];
		buf[39] = buf[37] ^ pre[1][i];    buf[66] = buf[70] ^ pre[2][i];
		buf[38] = buf[39] ^ pre[0][i];    buf[67] = buf[66] ^ pre[0][i];
		buf[34] = buf[38] ^ pre[2][i];    buf[65] = buf[67] ^ pre[1][i];
		buf[35] = buf[34] ^ pre[0][i];
		buf[33] = buf[35] ^ pre[1][i];    buf[64] = in[0][i] ^ pre[6][i];

		transpose_64x64(buf +  0, buf +  0);
		transpose_64x64(buf + 64, buf + 64);

		for (j = 0; j < 128; j++)
			out[ reversal[j] ][i] = buf[j];
	}

	for (i = 1; i <= 6; i++)
	{
		s = 1 << i;

		for (j = 0; j < 128; j += 2*s)
		for (k = j; k < j+s; k++)
		{
			vec_mul(tmp, out[k+s], fft_consts[ consts_ptr + (k-j) ]);

			for (b = 0; b < GFBITS; b++) out[k  ][b] ^= tmp[b];
			for (b = 0; b < GFBITS; b++) out[k+s][b] ^= out[k][b];
		}

		consts_ptr += (1 << i);
	}

	/* adding the part contributed by x^128 */

	for (i = 0; i < 128; i++)
	for (b = 0; b < GFBITS; b++)
		out[i][b] ^= fft_powers[i][b];
}

/* input: in, polynomial in bitsliced form */
/* output: out, bitsliced results of evaluating in all the field elements */
static void fft(vec out[][GFBITS], vec in[][GFBITS])
{
	radix_conversions(in);
	butterflies(out, in);
}

/* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c */
/*
  This file is for transpose of the Gao-Mateer FFT
  Functions with names ending with _tr are (roughly) the transpose of the corresponding functions in fft.c

  For the implementation strategy, see
  https://eprint.iacr.org/2017/793.pdf
*/
/* 20221230 djb: split these arrays into separate .c files */
/* 20221230 djb: rename consts array as fft_consts */
/* 20221230 djb: rename s array as fft_scalars_4x */
/* 20221230 djb: add linker lines */

/* linker define fft_tr */
/* linker use vec_mul */
/* linker use fft_scalars_4x fft_consts */




static void radix_conversions_tr(vec in[][ GFBITS ])
{
	int i, j, k;

	const vec mask[6][2] =
	{
		{0x2222222222222222, 0x4444444444444444},
		{0x0C0C0C0C0C0C0C0C, 0x3030303030303030},
		{0x00F000F000F000F0, 0x0F000F000F000F00},
		{0x0000FF000000FF00, 0x00FF000000FF0000},
		{0x00000000FFFF0000, 0x0000FFFF00000000},
		{0xFFFFFFFF00000000, 0x00000000FFFFFFFF}
	};

	/**/

	for (j = 6; j >= 0; j--)
	{
		if (j < 6)
		{
			vec_mul(in[0], in[0], fft_scalars_4x[j][0]); /* scaling */
			vec_mul(in[1], in[1], fft_scalars_4x[j][1]); /* scaling */
			vec_mul(in[2], in[2], fft_scalars_4x[j][2]); /* scaling */
			vec_mul(in[3], in[3], fft_scalars_4x[j][3]); /* scaling */
		}

		for (k = j; k <= 4; k++)
		for (i = 0; i < GFBITS; i++)
		{
			in[0][i] ^= (in[0][i] & mask[k][0]) << (1 << k);
			in[0][i] ^= (in[0][i] & mask[k][1]) << (1 << k);
			in[1][i] ^= (in[1][i] & mask[k][0]) << (1 << k);
			in[1][i] ^= (in[1][i] & mask[k][1]) << (1 << k);
			in[2][i] ^= (in[2][i] & mask[k][0]) << (1 << k);
			in[2][i] ^= (in[2][i] & mask[k][1]) << (1 << k);
			in[3][i] ^= (in[3][i] & mask[k][0]) << (1 << k);
			in[3][i] ^= (in[3][i] & mask[k][1]) << (1 << k);
		}

		if (j <= 5)
		for (i = 0; i < GFBITS; i++)
		{
			in[1][i] ^= in[0][i] >> 32;
			in[1][i] ^= in[1][i] << 32;

			in[3][i] ^= in[2][i] >> 32;
			in[3][i] ^= in[3][i] << 32;
		}

		for (i = 0; i < GFBITS; i++)
			in[3][i] ^= in[2][i] ^= in[1][i];
	}
}

static void butterflies_tr(vec out[][ GFBITS ], vec in[][ GFBITS ])
{
	int i, j, k, s, b;

	vec tmp[ GFBITS ];
	vec pre[6][2][ GFBITS ];
	vec buf[2][64];

	uint64_t consts_ptr = 128;

	const unsigned char reversal[128] =
	{
	  0, 64, 32, 96, 16, 80, 48, 112,
	  8, 72, 40, 104, 24, 88, 56, 120,
	  4, 68, 36, 100, 20, 84, 52, 116,
	  12, 76, 44, 108, 28, 92, 60, 124,
	  2, 66, 34, 98, 18, 82, 50, 114,
	  10, 74, 42, 106, 26, 90, 58, 122,
	  6, 70, 38, 102, 22, 86, 54, 118,
	  14, 78, 46, 110, 30, 94, 62, 126,
	  1, 65, 33, 97, 17, 81, 49, 113,
	  9, 73, 41, 105, 25, 89, 57, 121,
	  5, 69, 37, 101, 21, 85, 53, 117,
	  13, 77, 45, 109, 29, 93, 61, 125,
	  3, 67, 35, 99, 19, 83, 51, 115,
	  11, 75, 43, 107, 27, 91, 59, 123,
	  7, 71, 39, 103, 23, 87, 55, 119,
	  15, 79, 47, 111, 31, 95, 63, 127
	};

	const uint16_t beta[6] = {5246, 5306, 6039, 6685, 4905, 6755};

	/**/

	for (i = 6; i >= 0; i--)
	{
		s = 1 << i;
		consts_ptr -= s;

		for (j = 0; j < 128; j += 2*s)
		for (k = j; k < j+s; k++)
		{
			for (b = 0; b < GFBITS; b++) in[k][b] ^= in[k+s][b];

			vec_mul(tmp, in[k], fft_consts[ consts_ptr + (k-j) ]);

			for (b = 0; b < GFBITS; b++) in[k+s][b] ^= tmp[b];
		}
	}

	for (i = 0; i < GFBITS; i++)
	{
		for (k = 0; k < 128; k++)
			(&buf[0][0])[ k ] = in[ reversal[k] ][i];

		transpose_64x64(buf[0], buf[0]);
		transpose_64x64(buf[1], buf[1]);

		for (k = 0; k < 2; k++)
		{
			pre[0][k][i] = buf[k][32]; buf[k][33] ^= buf[k][32];
			pre[1][k][i] = buf[k][33]; buf[k][35] ^= buf[k][33];
			pre[0][k][i] ^= buf[k][35]; buf[k][34] ^= buf[k][35];
			pre[2][k][i] = buf[k][34]; buf[k][38] ^= buf[k][34];
			pre[0][k][i] ^= buf[k][38]; buf[k][39] ^= buf[k][38];
			pre[1][k][i] ^= buf[k][39]; buf[k][37] ^= buf[k][39];
			pre[0][k][i] ^= buf[k][37]; buf[k][36] ^= buf[k][37];
			pre[3][k][i] = buf[k][36]; buf[k][44] ^= buf[k][36];
			pre[0][k][i] ^= buf[k][44]; buf[k][45] ^= buf[k][44];
			pre[1][k][i] ^= buf[k][45]; buf[k][47] ^= buf[k][45];
			pre[0][k][i] ^= buf[k][47]; buf[k][46] ^= buf[k][47];
			pre[2][k][i] ^= buf[k][46]; buf[k][42] ^= buf[k][46];
			pre[0][k][i] ^= buf[k][42]; buf[k][43] ^= buf[k][42];
			pre[1][k][i] ^= buf[k][43]; buf[k][41] ^= buf[k][43];
			pre[0][k][i] ^= buf[k][41]; buf[k][40] ^= buf[k][41];
			pre[4][k][i] = buf[k][40]; buf[k][56] ^= buf[k][40];
			pre[0][k][i] ^= buf[k][56]; buf[k][57] ^= buf[k][56];
			pre[1][k][i] ^= buf[k][57]; buf[k][59] ^= buf[k][57];
			pre[0][k][i] ^= buf[k][59]; buf[k][58] ^= buf[k][59];
			pre[2][k][i] ^= buf[k][58]; buf[k][62] ^= buf[k][58];
			pre[0][k][i] ^= buf[k][62]; buf[k][63] ^= buf[k][62];
			pre[1][k][i] ^= buf[k][63]; buf[k][61] ^= buf[k][63];
			pre[0][k][i] ^= buf[k][61]; buf[k][60] ^= buf[k][61];
			pre[3][k][i] ^= buf[k][60]; buf[k][52] ^= buf[k][60];
			pre[0][k][i] ^= buf[k][52]; buf[k][53] ^= buf[k][52];
			pre[1][k][i] ^= buf[k][53]; buf[k][55] ^= buf[k][53];
			pre[0][k][i] ^= buf[k][55]; buf[k][54] ^= buf[k][55];
			pre[2][k][i] ^= buf[k][54]; buf[k][50] ^= buf[k][54];
			pre[0][k][i] ^= buf[k][50]; buf[k][51] ^= buf[k][50];
			pre[1][k][i] ^= buf[k][51]; buf[k][49] ^= buf[k][51];
			pre[0][k][i] ^= buf[k][49]; buf[k][48] ^= buf[k][49];
			pre[5][k][i] = buf[k][48]; buf[k][16] ^= buf[k][48];
			pre[0][k][i] ^= buf[k][16]; buf[k][17] ^= buf[k][16];
			pre[1][k][i] ^= buf[k][17]; buf[k][19] ^= buf[k][17];
			pre[0][k][i] ^= buf[k][19]; buf[k][18] ^= buf[k][19];
			pre[2][k][i] ^= buf[k][18]; buf[k][22] ^= buf[k][18];
			pre[0][k][i] ^= buf[k][22]; buf[k][23] ^= buf[k][22];
			pre[1][k][i] ^= buf[k][23]; buf[k][21] ^= buf[k][23];
			pre[0][k][i] ^= buf[k][21]; buf[k][20] ^= buf[k][21];
			pre[3][k][i] ^= buf[k][20]; buf[k][28] ^= buf[k][20];
			pre[0][k][i] ^= buf[k][28]; buf[k][29] ^= buf[k][28];
			pre[1][k][i] ^= buf[k][29]; buf[k][31] ^= buf[k][29];
			pre[0][k][i] ^= buf[k][31]; buf[k][30] ^= buf[k][31];
			pre[2][k][i] ^= buf[k][30]; buf[k][26] ^= buf[k][30];
			pre[0][k][i] ^= buf[k][26]; buf[k][27] ^= buf[k][26];
			pre[1][k][i] ^= buf[k][27]; buf[k][25] ^= buf[k][27];
			pre[0][k][i] ^= buf[k][25]; buf[k][24] ^= buf[k][25];
			pre[4][k][i] ^= buf[k][24]; buf[k][8] ^= buf[k][24];
			pre[0][k][i] ^= buf[k][8]; buf[k][9] ^= buf[k][8];
			pre[1][k][i] ^= buf[k][9]; buf[k][11] ^= buf[k][9];
			pre[0][k][i] ^= buf[k][11]; buf[k][10] ^= buf[k][11];
			pre[2][k][i] ^= buf[k][10]; buf[k][14] ^= buf[k][10];
			pre[0][k][i] ^= buf[k][14]; buf[k][15] ^= buf[k][14];
			pre[1][k][i] ^= buf[k][15]; buf[k][13] ^= buf[k][15];
			pre[0][k][i] ^= buf[k][13]; buf[k][12] ^= buf[k][13];
			pre[3][k][i] ^= buf[k][12]; buf[k][4] ^= buf[k][12];
			pre[0][k][i] ^= buf[k][4]; buf[k][5] ^= buf[k][4];
			pre[1][k][i] ^= buf[k][5]; buf[k][7] ^= buf[k][5];
			pre[0][k][i] ^= buf[k][7]; buf[k][6] ^= buf[k][7];
			pre[2][k][i] ^= buf[k][6]; buf[k][2] ^= buf[k][6];
			pre[0][k][i] ^= buf[k][2]; buf[k][3] ^= buf[k][2];
			pre[1][k][i] ^= buf[k][3]; buf[k][1] ^= buf[k][3];

			pre[0][k][i] ^= buf[k][1]; out[k][i] = buf[k][0] ^ buf[k][1];
		}
	}

	for (j = 0; j < GFBITS; j++) tmp[j] = vec_setbits((beta[0] >> j) & 1);

	vec_mul(out[2], pre[0][0], tmp);
	vec_mul(out[3], pre[0][1], tmp);

	for (i = 1; i < 6; i++)
	{
		for (j = 0; j < GFBITS; j++) tmp[j] = vec_setbits((beta[i] >> j) & 1);

		vec_mul(pre[i][0], pre[i][0], tmp);
		vec_mul(pre[i][1], pre[i][1], tmp);

		for (b = 0; b < GFBITS; b++)
		{
			out[2][b] ^= pre[i][0][b];
			out[3][b] ^= pre[i][1][b];
		}
	}

}

static void fft_tr(vec out[][GFBITS], vec in[][ GFBITS ])
{
	butterflies_tr(out, in);

	radix_conversions_tr(out);
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/gf.c */
/*
  this file is for functions for field arithmetic
*/
/* 20221231 djb: const for GF_mul */
/* 20221230 djb: add linker line */

/* linker define gf_iszero gf_mul gf_inv gf_frac GF_mul */



/* field multiplication */
gf gf_mul(gf in0, gf in1)
{
	int i;

	uint64_t tmp;
	uint64_t t0;
	uint64_t t1;
	uint64_t t;

	t0 = in0;
	t1 = in1;

	tmp = t0 * (t1 & 1);

	for (i = 1; i < GFBITS; i++)
		tmp ^= (t0 * (t1 & (1 << i)));

	/**/

	t = tmp & 0x1FF0000;
	tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);

	t = tmp & 0x000E000;
	tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);

	return tmp & GFMASK;
}

/* 2 field squarings */
static inline gf gf_sq2(gf in)
{
	int i;

	const uint64_t B[] = {0x1111111111111111,
	                      0x0303030303030303,
	                      0x000F000F000F000F,
	                      0x000000FF000000FF};

	const uint64_t M[] = {0x0001FF0000000000,
	                      0x000000FF80000000,
	                      0x000000007FC00000,
	                      0x00000000003FE000};

	uint64_t x = in;
	uint64_t t;

	x = (x | (x << 24)) & B[3];
	x = (x | (x << 12)) & B[2];
	x = (x | (x << 6)) & B[1];
	x = (x | (x << 3)) & B[0];

	for (i = 0; i < 4; i++)
	{
		t = x & M[i];
		x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
	}

	return x & GFMASK;
}

/* square and multiply */
static inline gf gf_sqmul(gf in, gf m)
{
	int i;

	uint64_t x;
	uint64_t t0;
	uint64_t t1;
	uint64_t t;

	const uint64_t M[] = {0x0000001FF0000000,
	                      0x000000000FF80000,
	                      0x000000000007E000};

	t0 = in;
	t1 = m;

	x = (t1 << 6) * (t0 & (1 << 6));

	t0 ^= (t0 << 7);

	x ^= (t1 * (t0 & (0x04001)));
	x ^= (t1 * (t0 & (0x08002))) << 1;
	x ^= (t1 * (t0 & (0x10004))) << 2;
	x ^= (t1 * (t0 & (0x20008))) << 3;
	x ^= (t1 * (t0 & (0x40010))) << 4;
	x ^= (t1 * (t0 & (0x80020))) << 5;

	for (i = 0; i < 3; i++)
	{
		t = x & M[i];
		x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
	}

	return x & GFMASK;
}

/* square twice and multiply */
static inline gf gf_sq2mul(gf in, gf m)
{
	int i;

	uint64_t x;
	uint64_t t0;
	uint64_t t1;
	uint64_t t;

	const uint64_t M[] = {0x1FF0000000000000,
		              0x000FF80000000000,
		              0x000007FC00000000,
	                      0x00000003FE000000,
	                      0x0000000001FE0000,
	                      0x000000000001E000};

	t0 = in;
	t1 = m;

	x = (t1 << 18) * (t0 & (1 << 6));

	t0 ^= (t0 << 21);

	x ^= (t1 * (t0 & (0x010000001)));
	x ^= (t1 * (t0 & (0x020000002))) << 3;
	x ^= (t1 * (t0 & (0x040000004))) << 6;
	x ^= (t1 * (t0 & (0x080000008))) << 9;
	x ^= (t1 * (t0 & (0x100000010))) << 12;
	x ^= (t1 * (t0 & (0x200000020))) << 15;

	for (i = 0; i < 6; i++)
	{
		t = x & M[i];
		x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
	}

	return x & GFMASK;
}

/* return num/den */
gf gf_frac(gf den, gf num)
{
	gf tmp_11;
	gf tmp_1111;
	gf out;

	tmp_11 = gf_sqmul(den, den); /* 11 */
	tmp_1111 = gf_sq2mul(tmp_11, tmp_11); /* 1111 */
	out = gf_sq2(tmp_1111);
	out = gf_sq2mul(out, tmp_1111); /* 11111111 */
	out = gf_sq2(out);
	out = gf_sq2mul(out, tmp_1111); /* 111111111111 */

	return gf_sqmul(out, num); /* 1111111111110 */
}

/* return 1/den */
gf gf_inv(gf den)
{
	return gf_frac(den, ((gf) 1));
}

/* check if a == 0 */
gf gf_iszero(gf a)
{
	uint32_t t = a;

	t -= 1;
	t >>= 19;

	return (gf) t;
}

/* multiplication in GF((2^m)^t) */
static void GF_mul(gf *out, const gf *in0, const gf *in1)
{
	int i, j;

	gf prod[255];

	for (i = 0; i < 255; i++)
		prod[i] = 0;

	for (i = 0; i < 128; i++)
		for (j = 0; j < 128; j++)
			prod[i+j] ^= gf_mul(in0[i], in1[j]);

	/**/

	for (i = 254; i >= 128; i--)
	{
		prod[i - 121] ^= prod[i];
		prod[i - 126] ^= prod[i];
		prod[i - 127] ^= prod[i];
		prod[i - 128] ^= prod[i];
	}

	for (i = 0; i < 128; i++)
		out[i] = prod[i];
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c */
/* 20221230 djb: add linker lines */
/* 20221230 djb: split out of operations.c */

/* linker define operation_dec */
/* linker use decrypt */




static void operation_dec(
       unsigned char *key,
       const unsigned char *c,
       const unsigned char *sk
)
{
	int i;

	unsigned char ret_decrypt = 0;

	uint16_t m;

	unsigned char e[ SYS_N/8 ];
	unsigned char preimage[ 1 + SYS_N/8 + SYND_BYTES ];
	unsigned char *x = preimage;
	const unsigned char *s = sk + 40 + IRR_BYTES + COND_BYTES;

	/**/

	ret_decrypt = decrypt(e, sk + 40, c);

	m = ret_decrypt;
	m -= 1;
	m >>= 8;

	*x++ = m & 1;
	for (i = 0; i < SYS_N/8; i++)
		*x++ = (~m & s[i]) | (m & e[i]);

	for (i = 0; i < SYND_BYTES; i++)
		*x++ = c[i];

	crypto_hash_32b(key, preimage, sizeof(preimage));
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c */
/* 20230102 djb: rename encrypt() as pke_encrypt() */
/* 20221230 djb: add linker lines */
/* 20221230 djb: split out of operations.c */

/* linker define operation_enc */
/* linker use pke_encrypt */




static void operation_enc(
       unsigned char *c,
       unsigned char *key,
       const unsigned char *pk
)
{
	unsigned char e[ SYS_N/8 ];
	unsigned char one_ec[ 1 + SYS_N/8 + SYND_BYTES ] = {1};

	/**/

	pke_encrypt(c, pk, e);

	memcpy(one_ec + 1, e, SYS_N/8);
	memcpy(one_ec + 1 + SYS_N/8, c, SYND_BYTES);

	crypto_hash_32b(key, one_ec, sizeof(one_ec));
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c */
/* 20221230 djb: add linker lines */
/* 20221230 djb: split out of operations.c */

/* linker define operation_keypair */
/* linker use controlbitsfrompermutation genpoly_gen pk_gen */




static void operation_keypair
(
       unsigned char *pk,
       unsigned char *sk
)
{
	int i;
	unsigned char seed[ 33 ] = {64};
	unsigned char r[ SYS_N/8 + (1 << GFBITS)*sizeof(uint32_t) + SYS_T*2 + 32 ];
	unsigned char *rp, *skp;
	uint64_t pivots = 0;

	gf f[ SYS_T ]; /* element in GF(2^mt) */
	gf irr[ SYS_T ]; /* Goppa polynomial */
	uint32_t perm[ 1 << GFBITS ]; /* random permutation as 32-bit integers */
	int16_t pi[ 1 << GFBITS ]; /* random permutation */

	randombytes(seed+1, 32);

	while (1)
	{
		rp = &r[ sizeof(r)-32 ];
		skp = sk;

		/* expanding and updating the seed */

		shake(r, sizeof(r), seed, 33);
		memcpy(skp, seed+1, 32);
		skp += 32 + 8;
		memcpy(seed+1, &r[ sizeof(r)-32 ], 32);

		/* generating irreducible polynomial */

		rp -= sizeof(f);

		for (i = 0; i < SYS_T; i++)
			f[i] = load_gf(rp + i*2);

		if (genpoly_gen(irr, f))
			continue;

		for (i = 0; i < SYS_T; i++)
			store_gf(skp + i*2, irr[i]);

		skp += IRR_BYTES;

		/* generating permutation */

		rp -= sizeof(perm);

		for (i = 0; i < (1 << GFBITS); i++)
			perm[i] = load4(rp + i*4);

		if (pk_gen(pk, skp - IRR_BYTES, perm, pi, &pivots))
			continue;

		controlbitsfrompermutation(skp, pi, GFBITS, 1 << GFBITS);
		skp += COND_BYTES;

		/* storing the random string s */

		rp -= SYS_N/8;
		memcpy(skp, rp, SYS_N/8);

		/* storing positions of the 32 pivots */

		store8(sk + 32, pivots);

		break;
	}
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c */
/*
  This file is for public-key generation
*/
/* 20221231 djb: remove unused min definition */
/* 20221231 djb: more 0 initialization to clarify data flow; tnx thom wiggers */
/* 20221230 djb: add linker lines */

/* linker define pk_gen */
/* linker use fft vec_inv vec_mul */



static crypto_uint64 uint64_is_equal_declassify(uint64_t t,uint64_t u)
{
  crypto_uint64 mask = crypto_uint64_equal_mask(t,u);
  crypto_declassify(&mask,sizeof mask);
  return mask;
}

static crypto_uint64 uint64_is_zero_declassify(uint64_t t)
{
  crypto_uint64 mask = crypto_uint64_zero_mask(t);
  crypto_declassify(&mask,sizeof mask);
  return mask;
}


static void de_bitslicing(uint64_t * out, const vec in[][GFBITS])
{
	int i, j, r;

	for (i = 0; i < (1 << GFBITS); i++)
		out[i] = 0 ;

	for (i = 0; i < 128; i++)
	for (j = GFBITS-1; j >= 0; j--)
	for (r = 0; r < 64; r++)
	{
		out[i*64 + r] <<= 1;
		out[i*64 + r] |= (in[i][j] >> r) & 1;
	}
}

static void to_bitslicing_2x(vec out0[][GFBITS], vec out1[][GFBITS], const uint64_t * in)
{
	int i, j, r;

	for (i = 0; i < 128; i++)
	{
		for (j = 0;j < GFBITS;++j) out0[i][j] = out1[i][j] = 0;

		for (j = GFBITS-1; j >= 0; j--)
		for (r = 63; r >= 0; r--)
		{
			out1[i][j] <<= 1;
			out1[i][j] |= (in[i*64 + r] >> (j + GFBITS)) & 1;
		}

		for (j = GFBITS-1; j >= 0; j--)
		for (r = 63; r >= 0; r--)
		{
			out0[i][GFBITS-1-j] <<= 1;
			out0[i][GFBITS-1-j] |= (in[i*64 + r] >> j) & 1;
		}
	}
}

/* return number of trailing zeros of in */
static inline int ctz(uint64_t in)
{
	int i, b, m = 0, r = 0;

	for (i = 0; i < 64; i++)
	{
		b = (in >> i) & 1;
		m |= b;
		r += (m^1) & (b^1);
	}

	return r;
}

static inline uint64_t same_mask(uint16_t x, uint16_t y)
{
        uint64_t mask;

        mask = x ^ y;
        mask -= 1;
        mask >>= 63;
        mask = -mask;

        return mask;
}

static int mov_columns(uint64_t mat[][ (SYS_N + 63) / 64 ], int16_t * pi, uint64_t * pivots)
{
	int i, j, k, s, block_idx, row;
	uint64_t buf[64], ctz_list[32], t, d, mask, one = 1;

	row = PK_NROWS - 32;
	block_idx = row/64;

	/* extract the 32x64 matrix */

	for (i = 0; i < 32; i++)
		buf[i] = (mat[ row + i ][ block_idx + 0 ] >> 32) |
		         (mat[ row + i ][ block_idx + 1 ] << 32);

	/* compute the column indices of pivots by Gaussian elimination. */
	/* the indices are stored in ctz_list */

	*pivots = 0;

	for (i = 0; i < 32; i++)
	{
		t = buf[i];
		for (j = i+1; j < 32; j++)
			t |= buf[j];

		if (uint64_is_zero_declassify(t)) return -1; /* return if buf is not full rank */

		ctz_list[i] = s = ctz(t);
		*pivots |= one << ctz_list[i];

		for (j = i+1; j < 32; j++) { mask = (buf[i] >> s) & 1; mask -= 1;    buf[i] ^= buf[j] & mask; }
		for (j = i+1; j < 32; j++) { mask = (buf[j] >> s) & 1; mask = -mask; buf[j] ^= buf[i] & mask; }
	}

	/* updating permutation */

	for (j = 0;   j < 32; j++)
	for (k = j+1; k < 64; k++)
	{
			d = pi[ row + j ] ^ pi[ row + k ];
			d &= same_mask(k, ctz_list[j]);
			pi[ row + j ] ^= d;
			pi[ row + k ] ^= d;
	}

	/* moving columns of mat according to the column indices of pivots */

	for (i = 0; i < PK_NROWS; i++)
	{
		t = (mat[ i ][ block_idx + 0 ] >> 32) |
		    (mat[ i ][ block_idx + 1 ] << 32);

		for (j = 0; j < 32; j++)
		{
			d  = t >> j;
			d ^= t >> ctz_list[j];
			d &= 1;

			t ^= d << ctz_list[j];
			t ^= d << j;
		}

		mat[ i ][ block_idx + 0 ] = (mat[ i ][ block_idx + 0 ] << 32 >> 32) | (t << 32);
		mat[ i ][ block_idx + 1 ] = (mat[ i ][ block_idx + 1 ] >> 32 << 32) | (t >> 32);
	}

	return 0;
}

static int pk_gen(unsigned char * pk, const unsigned char * irr, uint32_t * perm, int16_t * pi, uint64_t * pivots)
{
	const int nblocks_H = (SYS_N + 63) / 64;
	const int nblocks_I = (PK_NROWS + 63) / 64;

	int i, j, k;
	int row, c;

	uint64_t mat[ PK_NROWS ][ nblocks_H ];

	uint64_t mask;

	vec irr_int[2][ GFBITS ];

	vec consts[ 128 ][ GFBITS ];
	vec eval[ 128 ][ GFBITS ];
	vec prod[ 128 ][ GFBITS ];
	vec tmp[ GFBITS ];

	uint64_t list[1 << GFBITS];

	/* compute the inverses */

	irr_load(irr_int, irr);

	fft(eval, irr_int);

	vec_copy(prod[0], eval[0]);

	for (i = 1; i < 128; i++)
		vec_mul(prod[i], prod[i-1], eval[i]);

	vec_inv(tmp, prod[127]);

	for (i = 126; i >= 0; i--)
	{
		vec_mul(prod[i+1], prod[i], tmp);
		vec_mul(tmp, tmp, eval[i+1]);
	}

	vec_copy(prod[0], tmp);

	/* fill matrix */

	de_bitslicing(list, prod);

	for (i = 0; i < (1 << GFBITS); i++)
	{
		list[i] <<= GFBITS;
		list[i] |= i;
		list[i] |= ((uint64_t) perm[i]) << 31;
	}

	uint64_sort(list, 1 << GFBITS);

	for (i = 1; i < (1 << GFBITS); i++)
		if (uint64_is_equal_declassify(list[i-1] >> 31,list[i] >> 31))
			return -1;

	to_bitslicing_2x(consts, prod, list);

	for (i = 0; i < (1 << GFBITS); i++)
		pi[i] = list[i] & GFMASK;

	for (j = 0; j < nblocks_H; j++)
	for (k = 0; k < GFBITS; k++)
		mat[ k ][ j ] = prod[ j ][ k ];

	for (i = 1; i < SYS_T; i++)
	for (j = 0; j < nblocks_H; j++)
	{
		vec_mul(prod[j], prod[j], consts[j]);

		for (k = 0; k < GFBITS; k++)
			mat[ i*GFBITS + k ][ j ] = prod[ j ][ k ];
	}

	/* gaussian elimination */

	for (row = 0; row < PK_NROWS; row++)
	{
		i = row >> 6;
		j = row & 63;

		if (row == PK_NROWS - 32)
		{
			if (mov_columns(mat, pi, pivots))
				return -1;
		}

		for (k = row + 1; k < PK_NROWS; k++)
		{
			mask = mat[ row ][ i ] >> j;
			mask &= 1;
			mask -= 1;

			for (c = 0; c < nblocks_H; c++)
				mat[ row ][ c ] ^= mat[ k ][ c ] & mask;
		}

		if ( uint64_is_zero_declassify((mat[ row ][ i ] >> j) & 1) ) /* return if not systematic */
		{
			return -1;
		}

		for (k = 0; k < row; k++)
		{
			mask = mat[ k ][ i ] >> j;
			mask &= 1;
			mask = -mask;

			for (c = 0; c < nblocks_H; c++)
				mat[ k ][ c ] ^= mat[ row ][ c ] & mask;
		}

		for (k = row+1; k < PK_NROWS; k++)
		{
			mask = mat[ k ][ i ] >> j;
			mask &= 1;
			mask = -mask;

			for (c = 0; c < nblocks_H; c++)
				mat[ k ][ c ] ^= mat[ row ][ c ] & mask;
		}
	}

	for (i = 0; i < PK_NROWS; i++)
	{
		for (j = nblocks_I; j < nblocks_H-1; j++)
		{
			store8(pk, mat[i][j]);
			pk += 8;
		}

		store_i(pk, mat[i][j], PK_ROW_BYTES % 8);

                pk += PK_ROW_BYTES % 8;
	}

	/**/

	return 0;
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c */
/*
  This file is for secret-key generation
*/
/* 20221230 djb: add linker lines */

/* linker define genpoly_gen */
/* linker use gf_iszero gf_mul gf_inv GF_mul */



static inline crypto_uint16 gf_is_zero_declassify(gf t)
{
  crypto_uint16 mask = crypto_uint16_zero_mask(t);
  crypto_declassify(&mask,sizeof mask);
  return mask;
}

/* input: f, element in GF((2^m)^t) */
/* output: out, minimal polynomial of f */
/* return: 0 for success and -1 for failure */
static int genpoly_gen(gf *out, gf *f)
{
	int i, j, k, c;

	gf mat[ SYS_T+1 ][ SYS_T ];
	gf mask, inv, t;

	/* fill matrix */

	mat[0][0] = 1;

	for (i = 1; i < SYS_T; i++)
		mat[0][i] = 0;

	for (i = 0; i < SYS_T; i++)
		mat[1][i] = f[i];

	for (j = 2; j <= SYS_T; j++)
		GF_mul(mat[j], mat[j-1], f);

	/* gaussian */

	for (j = 0; j < SYS_T; j++)
	{
		for (k = j + 1; k < SYS_T; k++)
		{
			mask = gf_iszero(mat[ j ][ j ]);

			for (c = j; c < SYS_T + 1; c++)
				mat[ c ][ j ] ^= mat[ c ][ k ] & mask;

		}

		if ( gf_is_zero_declassify(mat[ j ][ j ]) ) /* return if not systematic */
		{
			return -1;
		}

		inv = gf_inv(mat[j][j]);

		for (c = j; c < SYS_T + 1; c++)
			mat[ c ][ j ] = gf_mul(mat[ c ][ j ], inv) ;

		for (k = 0; k < SYS_T; k++)
		{
			if (k != j)
			{
				t = mat[ j ][ k ];

				for (c = j; c < SYS_T + 1; c++)
					mat[ c ][ k ] ^= gf_mul(mat[ c ][ j ], t);
			}
		}
	}

	for (i = 0; i < SYS_T; i++)
		out[i] = mat[ SYS_T ][ i ];

	return 0;
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/vec.c */
/* 20221230 djb: add linker line */

/* linker define vec_mul vec_sq vec_inv */



static void vec_mul(vec * h, const vec * f, const vec * g)
{
	int i, j;
	vec buf[ 2*GFBITS-1 ];

	for (i = 0; i < 2*GFBITS-1; i++)
		buf[i] = 0;

	for (i = 0; i < GFBITS; i++)
	for (j = 0; j < GFBITS; j++)
		buf[i+j] ^= f[i] & g[j];

	for (i = 2*GFBITS-2; i >= GFBITS; i--)
	{
		buf[i-GFBITS+4] ^= buf[i];
		buf[i-GFBITS+3] ^= buf[i];
		buf[i-GFBITS+1] ^= buf[i];
		buf[i-GFBITS+0] ^= buf[i];
	}

	for (i = 0; i < GFBITS; i++)
		h[i] = buf[i];
}

/* bitsliced field squarings */
static void vec_sq(vec * out, vec * in)
{
	int i;
	vec result[GFBITS], t;

	t = in[11] ^ in[12];

	result[0] = in[0] ^ in[11];
	result[1] = in[7] ^ t;
	result[2] = in[1] ^ in[7];
	result[3] = in[8] ^ t;
	result[4] = in[2] ^ in[7];
	result[4] = result[4] ^ in[8];
	result[4] = result[4] ^ t;
	result[5] = in[7] ^ in[9];
	result[6] = in[3] ^ in[8];
	result[6] = result[6] ^ in[9];
	result[6] = result[6] ^ in[12];
	result[7] = in[8] ^ in[10];
	result[8] = in[4] ^ in[9];
	result[8] = result[8] ^ in[10];
	result[9] = in[9] ^ in[11];
	result[10] = in[5] ^ in[10];
	result[10] = result[10] ^ in[11];
	result[11] = in[10] ^ in[12];
	result[12] = in[6] ^ t;

	for (i = 0; i < GFBITS; i++)
		out[i] = result[i];
}

/* bitsliced field inverses */
static void vec_inv(vec * out, vec * in)
{
	vec tmp_11[ GFBITS ];
	vec tmp_1111[ GFBITS ];

	vec_copy(out, in);

	vec_sq(out, out);
	vec_mul(tmp_11, out, in); /* ^11 */

	vec_sq(out, tmp_11);
	vec_sq(out, out);
	vec_mul(tmp_1111, out, tmp_11); /* ^1111 */

	vec_sq(out, tmp_1111);
	vec_sq(out, out);
	vec_sq(out, out);
	vec_sq(out, out);
	vec_mul(out, out, tmp_1111); /* ^11111111 */

	vec_sq(out, out);
	vec_sq(out, out);
	vec_sq(out, out);
	vec_sq(out, out);
	vec_mul(out, out, tmp_1111); /* ^111111111111 */

	vec_sq(out, out); /* ^1111111111110 */
}


/* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c */

void mceliece6688128f_dec(uint8_t *key,
			  const uint8_t *c,
			  const uint8_t *sk)
{
  operation_dec((unsigned char*) key,
		(unsigned char*) c,
		(unsigned char*) sk);
}

/* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c */

void mceliece6688128f_enc(uint8_t *c,
			  uint8_t *key,
			  const uint8_t *pk)
{
  operation_enc((unsigned char*) c,
		(unsigned char*) key,
		(unsigned char*) pk);
}

/* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c */

void mceliece6688128f_keypair(uint8_t *pk,
			      uint8_t *sk)
{
  operation_keypair((unsigned char*) pk, (unsigned char*) sk);
}
